using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace XHandler.Controls { /// /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。 /// /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:WpfAppStepBar" /// /// /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:WpfAppStepBar;assembly=WpfAppStepBar" /// /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用, /// 并重新生成以避免编译错误: /// /// 在解决方案资源管理器中右击目标项目,然后依次单击 /// “添加引用”->“项目”->[浏览查找并选择此项目] /// /// /// 步骤 2) /// 继续操作并在 XAML 文件中使用控件。 /// /// /// /// public class StepBar : ItemsControl { #region Private属性 #endregion #region 依赖属性定义 public int StepIndex { get { return (int)GetValue(StepIndexProperty); } set { SetValue(StepIndexProperty, value); } } public static readonly DependencyProperty StepIndexProperty = DependencyProperty.Register("StepIndex", typeof(int), typeof(StepBar), new PropertyMetadata(0, OnStepIndexChanged)); private static void 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 OnStepIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { StepBar step = (StepBar)d; int stepIndex = (int)e.NewValue; step.UpdateStepItemState(stepIndex); } private void UpdateStepItemState(int stepIndex) { int count = Items.Count; if (count <= 0) { return; } for (int i = 0; i < Items.Count; i++) { if (ItemContainerGenerator.ContainerFromIndex(i) is StepBarItem stepItem) { stepItem.State = i < stepIndex ? StepState.Complete : i == stepIndex ? StepState.Busy : StepState.Default; int a = 0; } } } #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); UpdateStepItemState(this.StepIndex); } 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); } } //进度重新回到第一个 //int a=this.StepIndex ; } #endregion #region Private方法 #endregion public void Next() { if (StepIndex >= Items.Count) { StepIndex = Items.Count - 1; } StepIndex++; } public void Prev() { if (StepIndex < 0) { StepIndex = -1; } else { StepIndex--; } } } }