基于WPF实现步骤控件的示例代码

这篇文章主要为大家详细介绍了WPF实现简单的步骤控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

WPF 实现步骤控件

框架使用.NET40

Visual Studio 2019;

Step 继承 ItemsControl 使用 Grid 嵌套 ProgressBar 和 ItemsPresenter.

  • ProgressBar 用来当作步骤后面的线条,宽等于控件的(ActualWidth / Items.Count) * (Items.Count - 1),Maximum = Items.Count - 1
  • ItemsPresenter 用来展示步骤 Item 。

ItemsPanel - ItemsPanelTemplate - UniformGrid Rows="1" 横向展示,UniformGrid Columns="1" 可以控制竖向显示,只不过需要重新自定义 ItemContainerStyle 的样式。

然后创建 StepItem 继承 ContentControl 增加两个属性 Index 用来记录当前是步骤 与 State 记录状态 (等待中、进行中、已完成)。

因为继承了 ContentControl 所以可以在使用时指定 Content 显示内容,在每个步骤下方显示。

实现代码

1) Step.xaml 代码如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

2) Step.cs 代码如下:

using System; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Media; namespace WPFDevelopers.Controls {     [TemplatePart(Name = ProgressBarTemplateName, Type = typeof(ProgressBar))]     public class Step : ItemsControl     {         private const string ProgressBarTemplateName = "PART_ProgressBar";         private ProgressBar _progressBar;         public int StepIndex         {             get => (int)GetValue(StepIndexProperty);             set => SetValue(StepIndexProperty, value);         }         public static readonly DependencyProperty StepIndexProperty = DependencyProperty.Register(            "StepIndex", typeof(int), typeof(Step), new PropertyMetadata(0, OnStepIndexChanged));         private static void OnStepIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             var step = (Step)d;             var stepIndex = (int)e.NewValue;             step.UpdateStepItemState(stepIndex);         }         void UpdateStepItemState(int stepIndex)         {             var count = Items.Count;             if (count <= 0) return;             if (stepIndex >= count)             {                 StepIndex--;                 return;             }             if (stepIndex < 0)             {                 StepIndex++;                 return;             }             for (var i = 0; i < stepIndex; i++)             {                 if (ItemContainerGenerator.ContainerFromIndex(i) is StepItem stepItem)                     stepItem.Status = Status.Complete;             }             if (ItemContainerGenerator.ContainerFromIndex(stepIndex) is StepItem itemInProgress)                 itemInProgress.Status = Status.InProgress;             for (var i = stepIndex + 1; i < Items.Count; i++)             {                 if (ItemContainerGenerator.ContainerFromIndex(i) is StepItem stepItem)                     stepItem.Status = Status.Waiting;             }         }         public override void OnApplyTemplate()         {             base.OnApplyTemplate();             _progressBar = GetTemplateChild(ProgressBarTemplateName) as ProgressBar;         }         protected override void OnRender(DrawingContext drawingContext)         {             base.OnRender(drawingContext);             var count = Items.Count;             if (_progressBar == null || count <= 0) return;             _progressBar.Maximum = count - 1;             _progressBar.Value = StepIndex;             _progressBar.Width = (ActualWidth / count) * (count - 1);         }         protected override bool IsItemItsOwnContainerOverride(object item)         {             return item is StepItem;         }         protected override DependencyObject GetContainerForItemOverride()         {             return new StepItem();         }         public Step()         {             ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;         }         public void Next()         {             StepIndex++;         }         public void Previous()         {             StepIndex--;         }         private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)         {             if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)             {                 var count = Items.Count;                 if (count <= 0) return;                 UpdateStepItemState(StepIndex);             }         }     } } 

3) StepItem.cs 代码如下:

using System.Windows; using System.Windows.Controls; namespace WPFDevelopers.Controls {     public class StepItem : ContentControl     {         public static readonly DependencyProperty IndexProperty = DependencyProperty.Register(             "Index", typeof(int), typeof(StepItem), new PropertyMetadata(-1));         public int Index         {             get => (int)GetValue(IndexProperty);             internal set => SetValue(IndexProperty, value);         }         public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(             "Status", typeof(Status), typeof(StepItem), new PropertyMetadata(Status.Waiting));         public Status Status         {             get => (Status)GetValue(StatusProperty);             internal set => SetValue(StatusProperty, value);         }     } } 

4) Status.cs 代码如下:

namespace WPFDevelopers.Controls {     ///      ///状态值     ///      public enum Status     {         ///          /// 等待中         ///          Waiting,         ///          /// 正在进行中         ///          InProgress,         ///          /// 完成         ///          Complete     } } 

5) StepExample.xaml 代码如下:

                                                                                                                                                                                                                                                                                                                                                   

6) StepExample.xaml.cs 代码如下:

using System; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using WPFDevelopers.Controls; using WPFDevelopers.Samples.Helpers; namespace WPFDevelopers.Samples.ExampleViews {     ///      /// StepExample.xaml 的交互逻辑     ///      public partial class StepExample : UserControl     {         public ObservableCollection Steps         {             get;             set;         }         public StepExample()         {             InitializeComponent();             Steps = new ObservableCollection();             Steps.Add("Step 1");             Steps.Add("Step 2");             Steps.Add("Step 3");             Steps.Add("Step 4");             this.DataContext = this;         }         public ICommand NextCommand => new RelayCommand(new Action((sender) =>         {             var uniformGrid = sender as UniformGrid;             if (uniformGrid == null) return;             foreach (var step in uniformGrid.Children.OfType())                 step.Next();         }));         public ICommand PreviousCommand => new RelayCommand(new Action((sender) =>         {             var uniformGrid = sender as UniformGrid;             if (uniformGrid == null) return;             foreach (var step in uniformGrid.Children.OfType())                 step.Previous();         }));     } }

效果图

以上就是基于WPF实现步骤控件的示例代码的详细内容,更多关于WPF步骤控件的资料请关注0133技术站其它相关文章!

以上就是基于WPF实现步骤控件的示例代码的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 其他教程