WPF教程002 - 实现Step步骤条控件
在网上看到这么一个效果,刚好在用WPF做控件,就想着用WPF来实现一下

1、实现原理
2、控件实现
public class StepBar : ItemsControl
{
#region Constructors
static StepBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBar), new FrameworkPropertyMetadata(typeof(StepBar)));
}
#endregion
}
public class StepBarItem : ContentControl
{
#region Constructors
static StepBarItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBarItem), new FrameworkPropertyMetadata(typeof(StepBarItem)));
}
#endregion
}
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ec="http://schemas.microsoft.com/expression/2010/controls"
xmlns:ZUI="clr-namespace:ZdfFlatUI"
xmlns:Converters="clr-namespace:ZdfFlatUI.Converters">
<Converters:IsLastItemConverter x:Key="IsLastItemConverter" />
<Converters:IsProgressedConverter x:Key="IsProgressedConverter" />
<PathGeometry x:Key="Icon_Gou" Figures="M378.410667 850.450963C364.491852 850.450963 350.610963 845.293037 340.02963 834.939259L20.920889 523.529481C-0.279704 502.821926-0.279704 469.295407 20.920889 448.587852 42.121481 427.880296 76.48237 427.880296 97.682963 448.587852L378.410667 722.526815 925.75763 188.491852C946.958222 167.784296 981.319111 167.784296 1002.519704 188.491852 1023.720296 209.161481 1023.720296 242.688 1002.519704 263.395556L416.791704 834.939259C406.172444 845.293037 392.291556 850.450963 378.410667 850.450963L378.410667 850.450963Z" />
<Style TargetType="{x:Type ZUI:StepBarItem}">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontFamily" Value="宋体" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ZUI:StepBarItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Grid Margin="0,0,10,0">
<Border x:Name="Bd" BorderBrush="#CCCCCC" Width="25" Height="25" CornerRadius="100"
BorderThickness="1" SnapsToDevicePixels="True" UseLayoutRounding="True">
</Border>
<TextBlock x:Name="Number" Text="{TemplateBinding Number}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<Path x:Name="path" Data="{StaticResource Icon_Gou}" Stretch="Uniform" Width="12" Fill="#3399FF" Visibility="Collapsed" />
</Grid>
<ContentPresenter VerticalAlignment="Center" />
</StackPanel>
<Border x:Name="Line" Grid.Column="1" BorderBrush="#E3E8EE" BorderThickness="0,1,0,0"
VerticalAlignment="Center" Margin="10,0"
SnapsToDevicePixels="True" UseLayoutRounding="True" />
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsLastItemConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ZUI:StepBar}}" Path="Items.Count"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsLastItemConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ZUI:StepBar}}" Path="Items.Count"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Line" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Value="Less">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsProgressedConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ZUI:StepBar}}" Path="Progress"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Bd" Property="Background" Value="#003399FF" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#3399FF" />
<Setter TargetName="Number" Property="Visibility" Value="Collapsed" />
<Setter TargetName="Line" Property="BorderBrush" Value="#3399FF" />
<Setter TargetName="path" Property="Visibility" Value="Visible" />
<Setter Property="Foreground" Value="#999999" />
</DataTrigger>
<DataTrigger Value="Equal">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsProgressedConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ZUI:StepBar}}" Path="Progress"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Bd" Property="Background" Value="#3399FF" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#3399FF" />
<Setter TargetName="Number" Property="Visibility" Value="Visible" />
<Setter TargetName="Number" Property="Foreground" Value="#FFFFFF" />
<Setter TargetName="path" Property="Visibility" Value="Collapsed" />
<Setter Property="Foreground" Value="#666666" />
</DataTrigger>
<DataTrigger Value="Large">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsProgressedConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ZUI:StepBar}}" Path="Progress"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" Value="#999999" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ZUI:StepBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ZUI:StepBar}">
<Border>
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="True" Rows="1" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace ZdfFlatUI.Converters
{
public class IsProgressedConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if ((values[0] is ContentControl && values[1] is int) == false)
{
return EnumCompare.None;
}
ContentControl contentControl = values[0] as ContentControl;
int progress = (int)values[1];
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentControl);
if(itemsControl == null)
{
return EnumCompare.None;
}
int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentControl);
if(index < progress)
{
return EnumCompare.Less;
}
else if(index == progress)
{
return EnumCompare.Equal;
}
return EnumCompare.Large;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace ZdfFlatUI.Converters
{
/// <summary>
/// true则隐藏,false则显示
/// </summary>
public class IsLastItemConverter : IMultiValueConverter
{
#region IValueConverter 成员
public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ContentControl contentPresenter = value[0] as ContentControl;
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentPresenter);
bool flag = false;
if(itemsControl != null)
{
int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentPresenter);
flag = (index == (itemsControl.Items.Count - 1));
}
return flag;
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace ZdfFlatUI
{
public class StepBar : ItemsControl
{
#region Private属性
#endregion
#region 依赖属性定义
public int Progress
{
get { return (int)GetValue(ProgressProperty); }
set { SetValue(ProgressProperty, value); }
}
public static readonly DependencyProperty ProgressProperty =
DependencyProperty.Register("Progress", typeof(int), typeof(StepBar), new PropertyMetadata(0, OnProgressChangedCallback, OnProgressCoerceValueCallback));
private static object OnProgressCoerceValueCallback(DependencyObject d, object baseValue)
{
//不让Progress超出边界
StepBar stepBar = d as StepBar;
int newValue = Convert.ToInt32(baseValue);
if (newValue < 0)
{
return 0;
}
else if(newValue >= stepBar.Items.Count)
{
return stepBar.Items.Count - 1;
}
return newValue;
}
private static void OnProgressChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
#endregion
#region 依赖属性set get
#endregion
#region Constructors
static StepBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBar), new FrameworkPropertyMetadata(typeof(StepBar)));
}
#endregion
#region Override方法
protected override DependencyObject GetContainerForItemOverride()
{
return new StepBarItem();
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
//设置Item的显示数字
StepBarItem stepBarItem = element as StepBarItem;
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(stepBarItem);
int index = itemsControl.ItemContainerGenerator.IndexFromContainer(stepBarItem);
stepBarItem.Number = Convert.ToString(++index);
base.PrepareContainerForItemOverride(element, item);
}
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
//ItemsControl数量变化时,重新设置各个Item的显示的数字
for (int i = 0; i < this.Items.Count; i++)
{
StepBarItem stepBarItem = this.ItemContainerGenerator.ContainerFromIndex(i) as StepBarItem;
if(stepBarItem != null)
{
int temp = i;
stepBarItem.Number = Convert.ToString(++temp);
}
}
//进度重新回到第一个
this.Progress = 0;
}
#endregion
#region Private方法
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace ZdfFlatUI
{
public class StepBarItem : ContentControl
{
#region Private属性
#endregion
#region 依赖属性定义
public string Number
{
get { return (string)GetValue(NumberProperty); }
set { SetValue(NumberProperty, value); }
}
public static readonly DependencyProperty NumberProperty =
DependencyProperty.Register("Number", typeof(string), typeof(StepBarItem));
#endregion
#region 依赖属性set get
#endregion
#region Constructors
static StepBarItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBarItem), new FrameworkPropertyMetadata(typeof(StepBarItem)));
}
#endregion
#region Override方法
#endregion
#region Private方法
#endregion
}
}
3、控件的具体使用
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock x:Name="text" Text="{Binding ., StringFormat=当前正在进行 {0} 步}" Foreground="#957180" FontSize="14" Margin="0,0,0,20" />
<WPF.UI:StepBar x:Name="stepBar1" Width="900" Margin="0,20,0,0" />
<StackPanel Orientation="Horizontal">
<WPF.UI:FlatButton Width="70" Height="28" CornerRadius="3" Click="FlatButton_Click1" Content="Previous" Margin="10,20" />
<WPF.UI:FlatButton Width="70" Height="28" CornerRadius="3" Click="FlatButton_Click" Content="Next" Margin="10,10" />
<WPF.UI:FlatButton Width="70" Height="28" CornerRadius="3" Click="btn_AddItem" Content="Add" Margin="10,10" />
<WPF.UI:FlatButton Width="70" Height="28" CornerRadius="3" Click="btn_RemoveItem" Content="Remove" Margin="10,10" />
</StackPanel>
</StackPanel>
public partial class UCTStepBarTest : UserControl
{
private int _Step;
public int Step
{
get
{
int temp = this.stepBar.Progress;
return ++temp;
}
}
ObservableCollection<string> list = new ObservableCollection<string>();
public UCTStepBarTest()
{
InitializeComponent();
list.Add("已完成");
list.Add("进行中");
list.Add("已完成");
list.Add("进行中");
this.stepBar1.ItemsSource = list;
this.text.DataContext = Step;
}
private void FlatButton_Click(object sender, RoutedEventArgs e)
{
this.stepBar1.Progress++;
this.text.DataContext = Step;
}
private void FlatButton_Click1(object sender, RoutedEventArgs e)
{
this.stepBar1.Progress--;
this.text.DataContext = Step;
}
private void btn_AddItem(object sender, RoutedEventArgs e)
{
list.Add("进行中");
}
private void btn_RemoveItem(object sender, RoutedEventArgs e)
{
list.RemoveAt(0);
this.text.DataContext = Step;
}
}

WPF教程002 - 实现Step步骤条控件的更多相关文章
- C#开发step步骤条控件
现在很多的javascript控件,非常的不错,其中step就是一个,如下图所示: 那么如何用C#来实现一个step控件呢? 先定义一个StepEntity类来存储步骤条节点的信息: public c ...
- WPF-自定义实现步骤条控件
步骤条实现的效果: 步骤条控件是在listbox的基础上实现的. 一. xaml代码: <Window.Resources> <convert1:StepListBarWidthCo ...
- Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
现在如果想打造一款专业的App,UI的设计和操作的简便性相当重要.UI设计可以借助Photoshop或者AI等设计工具,之前了解到WPF设计工具Expression Blend可以直接导入PSD文件或 ...
- 示例:WPF中Slider控件封装的缓冲播放进度条控件
原文:示例:WPF中Slider控件封装的缓冲播放进度条控件 一.目的:模仿播放器播放进度条,支持缓冲任务功能 二.进度: 实现类似播放器中带缓存的播放样式(播放区域.缓冲区域.全部区域等样式) 实现 ...
- DevExpress的进度条控件ProgressBarControl的使用-以ZedGraph添加曲线进度为例
场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...
- WPF中嵌入WinForm中的webbrowser控件
原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能 ...
- HslControls组件库 工业控件库 曲线控件 时间控件 管道控件 温度计控件 阀门控件 传送带控件 进度条控件 电池控件 数码管控件等等
本篇博客主要对 HslControls 组件做一个大概的总览介绍,更详细的内容可以参照页面里的子链接,还有github上的源代码,然后进行相关的学习,和使用. Prepare 先从nuget下载到组件 ...
- WPF 构建无外观(Lookless)控件
原文:WPF 构建无外观(Lookless)控件 构建一个用户可以使用Template属性设置外观的WPF控件需要以下几步 1.继承自System.Windows.Controls.Control 2 ...
- WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探
原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探 最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...
随机推荐
- ModSecurity防御暴力破解
http://www.modsecurity.org/ ModSecurity防御暴力破解 在阅读本文前,先简单了解下什么是ModSecurity,ModSecurity是一个入侵探测与阻止的引擎.它 ...
- 使用xerces库的一个注意事项
作者:朱金灿 来源:http://blog.csdn.net/clever101 使用xerces库解析xml文件,结果出现这样一些链接错误: public: static classxercesc_ ...
- python opencv3 —— findContours
findContours 是 opencv 下的轮廓提取函数. 1. api 分析 findContours(image, mode, method[, contours[, hierarchy[, ...
- VMware虚拟机12安装linux系统详细教程
亲测有效,附图: 工具/原料 VM ware workstation12虚拟机(百度下载) 深度linux镜像ios系统文件 链接:https://pan.baidu.com/s/1RY1Plgru4 ...
- mysqldump 不需要密码
-p 参数比较特殊,正确语法是 -ppassword,即-p和密码中间不能有空格. 请教:数据库备份命令如果这样写mysqldump -u root -p dataname>/home/data ...
- Java中String推断相等equals与==的差别以及StringBuilder的equals
Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的"相等"有所不同,接下来进行分析,结论由程序进行验证 Str ...
- 【u004】数列
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有这样一种数列A1.A2.A3.--An,其中A1=0,且对任意一项Ai满足|Ai-A(i+1)|=1 ...
- 手把手教你完成App支付JAVA后台-支付宝支付JAVA
接着上一篇博客,我们暂时完成了手机端的部分支付代码,接下来,我们继续写后台的代码. 后台基本需要到以下几个参数,我都将他们写在了properties文件中: 支付宝参数 AliPay.payURL = ...
- php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)
php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...
- mysql修改root密码百分百解决你的问题
原文:mysql修改root密码百分百解决你的问题 1.MySQL版本8.0.4之后修改密码 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_n ...