基于WPF實現(xiàn)步驟控件的示例代碼
WPF 實現(xiàn)步驟控件
框架使用.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
的樣式。
然后創(chuàng)建 StepItem
繼承 ContentControl
增加兩個屬性 Index
用來記錄當前是步驟 與 State
記錄狀態(tài) (等待中、進行中、已完成)。
因為繼承了 ContentControl
所以可以在使用時指定 Content
顯示內(nèi)容,在每個步驟下方顯示。
實現(xiàn)代碼
1) Step.xaml
代碼如下:
<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ????????????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ????????????????????xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" ????????????????????xmlns:controls="clr-namespace:WPFDevelopers.Controls" ????????????????????xmlns:converts="clr-namespace:WPFDevelopers.Converts"> ????<ResourceDictionary.MergedDictionaries> ????????<ResourceDictionary?Source="Basic/ControlBasic.xaml"/> ????</ResourceDictionary.MergedDictionaries> ????<converts:IndexConverter?x:Key="IndexConverter"/> ????<Style?x:Key="DefaultStepItem"?TargetType="{x:Type?controls:StepItem}" ???????????BasedOn="{StaticResource?ControlBasicStyle}"> ????????<Setter?Property="BorderThickness"?Value="1"/> ????????<Setter?Property="Template"> ????????????<Setter.Value> ????????????????<ControlTemplate?TargetType="{x:Type?controls:StepItem}"> ????????????????????<StackPanel> ????????????????????????<controls:SmallPanel> ????????????????????????????<Ellipse? ????????????????????????????????????Width="45" ????????????????????????????????????Height="30" ????????????????????????????????????Fill="{DynamicResource?WindowForegroundColorBrush}" ????????????????????????????????????HorizontalAlignment="Center"/> ????????????????????????????<Border? ????????????????????????????????????????Background="{TemplateBinding?Background}" ????????????????????????????????????????HorizontalAlignment="Center" ????????????????????????????????????????CornerRadius="15" ????????????????????????????????????????BorderThickness="{TemplateBinding?BorderThickness}" ????????????????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}" ????????????????????????????????????????Height="30"? ????????????????????????????????????????Width="30"> ????????????????????????????????<controls:SmallPanel> ????????????????????????????????????<TextBlock?Foreground="{TemplateBinding?Foreground}"? ???????????????????????????????????????????????????????VerticalAlignment="Center" ???????????????????????????????????????????????????????HorizontalAlignment="Center" ???????????????????????????????????????????????????????FontSize="{TemplateBinding?FontSize}" ???????????????????????????????????????????????????????Text="{Binding?RelativeSource={RelativeSource?FindAncestor,?AncestorType={x:Type?controls:StepItem}},?Converter={StaticResource?IndexConverter}}" ???????????????????????????????????????????????????????Name="PART_Index"/> ????????????????????????????????????<Path?Data="{StaticResource?PathComplete}" ??????????????????????????????????????????????????Fill="{TemplateBinding?Foreground}" ??????????????????????????????????????????????????Stretch="Uniform" ??????????????????????????????????????????????????Width="12" ??????????????????????????????????????????????????Height="12" ??????????????????????????????????????????????????Name="PART_PathComplete" ??????????????????????????????????????????????????Visibility="Collapsed"/> ????????????????????????????????</controls:SmallPanel> ????????????????????????????</Border> ????????????????????????</controls:SmallPanel> ????????????????????????<ContentPresenter?HorizontalAlignment="Center"? ??????????????????????????????????????????????????TextElement.FontWeight="Black" ??????????????????????????????????????????????????ContentTemplate="{Binding?ItemTemplate,RelativeSource={RelativeSource?AncestorType=controls:Step}}" ??????????????????????????????????????????????????TextElement.Foreground="{DynamicResource?RegularTextSolidColorBrush}" ??????????????????????????????????????????????????Margin="0,6,0,0"/> ????????????????????</StackPanel> ????????????????????<ControlTemplate.Triggers> ????????????????????????<Trigger?Property="Status"?Value="Waiting"> ????????????????????????????<Setter?Property="Foreground"?Value="{DynamicResource?PrimaryTextSolidColorBrush}"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_PathComplete"?Value="Collapsed"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_Index"?Value="Visible"/> ????????????????????????????<Setter?Property="Background"?Value="{DynamicResource?BaseSolidColorBrush}"/> ????????????????????????</Trigger> ????????????????????????<Trigger?Property="Status"?Value="InProgress"> ????????????????????????????<Setter?Property="Foreground"?Value="{DynamicResource?DefaultBackgroundSolidColorBrush}"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_PathComplete"?Value="Collapsed"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_Index"?Value="Visible"/> ????????????????????????????<Setter?Property="Background"?Value="{DynamicResource?PrimaryNormalSolidColorBrush}"/> ????????????????????????</Trigger> ????????????????????????<Trigger?Property="Status"?Value="Complete"> ????????????????????????????<Setter?Property="BorderBrush"?Value="{DynamicResource?DefaultBackgroundSolidColorBrush}"/> ????????????????????????????<Setter?Property="Background"?Value="{DynamicResource?DefaultBackgroundSolidColorBrush}"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_PathComplete"?Value="Visible"/> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_Index"?Value="Collapsed"/> ????????????????????????????<Setter?Property="Foreground"?Value="{DynamicResource?PrimaryNormalSolidColorBrush}"/> ????????????????????????</Trigger> ????????????????????</ControlTemplate.Triggers> ????????????????</ControlTemplate> ????????????</Setter.Value> ????????</Setter> ????</Style> ????<Style?x:Key="DefaultStep"?TargetType="{x:Type?controls:Step}"? ???????????BasedOn="{StaticResource?ControlBasicStyle}"> ????????<Setter?Property="ItemContainerStyle"?Value="{StaticResource?DefaultStepItem}"/> ????????<Setter?Property="VerticalContentAlignment"?Value="Top"/> ????????<Setter?Property="HorizontalContentAlignment"?Value="Center"/> ????????<Setter?Property="Template"> ????????????<Setter.Value> ????????????????<ControlTemplate?TargetType="{x:Type?controls:Step}"> ????????????????????<controls:SmallPanel> ????????????????????????<ProgressBar?x:Name="PART_ProgressBar"? ?????????????????????????????????????????????Margin="0,18" ?????????????????????????????????????????????Height="1" ?????????????????????????????????????????????Value="{Binding?StepIndex,RelativeSource={RelativeSource?AncestorType=controls:Step}}" ?????????????????????????????????????????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}" ?????????????????????????????????????????????HorizontalAlignment="{TemplateBinding?HorizontalContentAlignment}"/> ????????????????????????<ItemsPresenter/> ????????????????????</controls:SmallPanel> ????????????????</ControlTemplate> ????????????</Setter.Value> ????????</Setter> ????????<Setter?Property="ItemsPanel"> ????????????<Setter.Value> ????????????????<ItemsPanelTemplate> ????????????????????<UniformGrid?Rows="1"/> ????????????????</ItemsPanelTemplate> ????????????</Setter.Value> ????????</Setter> ????</Style> ????<Style?TargetType="{x:Type?controls:StepItem}"?BasedOn="{StaticResource?DefaultStepItem}"?/> ????<Style?TargetType="{x:Type?controls:Step}"?BasedOn="{StaticResource?DefaultStep}"?/> </ResourceDictionary>
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 { ????///?<summary> ????///狀態(tài)值 ????///?</summary> ????public?enum?Status ????{ ????????///?<summary> ????????///?等待中 ????????///?</summary> ????????Waiting, ????????///?<summary> ????????///?正在進行中 ????????///?</summary> ????????InProgress, ????????///?<summary> ????????///?完成 ????????///?</summary> ????????Complete ????} }
5) StepExample.xaml
代碼如下:
<UserControl?x:Class="WPFDevelopers.Samples.ExampleViews.StepExample" ?????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ?????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ?????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"? ?????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"? ?????????????xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls" ?????????????xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" ?????????????xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" ?????????????mc:Ignorable="d"? ?????????????d:DesignHeight="450"?d:DesignWidth="800"> ????<controls:CodeViewer> ????????<StackPanel??VerticalAlignment="Center"?> ????????????<UniformGrid?Columns="2"?Name="PART_UniformGrid"> ????????????????<wd:Step?x:Name="PART_Step"?StepIndex="{Binding?Progress}"> ????????????????????<wd:StepItem?Content="填寫賬號"/> ????????????????????<wd:StepItem?Content="身份驗證"/> ????????????????????<wd:StepItem?Content="設置新密碼"/> ????????????????????<wd:StepItem?Content="完成"/> ????????????????</wd:Step> ????????????????<wd:Step?StepIndex="0"?ItemsSource="{Binding?Steps}"> ????????????????</wd:Step> ????????????</UniformGrid> ????????????<StackPanel?Orientation="Horizontal" ????????????????????????VerticalAlignment="Center"? ????????????????????????HorizontalAlignment="Center" ????????????????????????Margin="10"> ????????????????<Button?Content="上一步"??Command="{Binding?PreviousCommand}"? ????????????????????CommandParameter="{Binding?ElementName=PART_UniformGrid}" ????????????????????Style="{StaticResource?PrimaryButton}"/> ????????????????<Button?Content="下一步"???Command="{Binding?NextCommand}"? ????????????????????CommandParameter="{Binding?ElementName=PART_UniformGrid}" ????????????????????Style="{StaticResource?PrimaryButton}"/> ??????????????? ????????????</StackPanel> ???????????? ????????</StackPanel> ????????<controls:CodeViewer.SourceCodes> ????????????<controls:SourceCodeModel? ????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/StepExample.xaml"? ????????????????CodeType="Xaml"/> ????????????<controls:SourceCodeModel? ????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/StepExample.xaml.cs"? ????????????????CodeType="CSharp"/> ????????</controls:CodeViewer.SourceCodes> ????</controls:CodeViewer> </UserControl>
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 { ????///?<summary> ????///?StepExample.xaml?的交互邏輯 ????///?</summary> ????public?partial?class?StepExample?:?UserControl ????{ ????????public?ObservableCollection<string>?Steps ????????{ ????????????get; ????????????set; ????????} ????????public?StepExample() ????????{ ????????????InitializeComponent(); ????????????Steps?=?new?ObservableCollection<string>(); ????????????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<object>((sender)?=> ????????{ ????????????var?uniformGrid?=?sender?as?UniformGrid; ????????????if?(uniformGrid?==?null)?return; ????????????foreach?(var?step?in?uniformGrid.Children.OfType<Step>()) ????????????????step.Next(); ????????})); ????????public?ICommand?PreviousCommand?=>?new?RelayCommand(new?Action<object>((sender)?=> ????????{ ????????????var?uniformGrid?=?sender?as?UniformGrid; ????????????if?(uniformGrid?==?null)?return; ????????????foreach?(var?step?in?uniformGrid.Children.OfType<Step>()) ????????????????step.Previous(); ????????})); ????} }
效果圖
以上就是基于WPF實現(xiàn)步驟控件的示例代碼的詳細內(nèi)容,更多關于WPF步驟控件的資料請關注腳本之家其它相關文章!
相關文章
C#調(diào)用C動態(tài)鏈接庫的實現(xiàn)
動態(tài)鏈接庫是不能直接執(zhí)行的,也不能接收消息,它只是一個獨立的文件,本文主要介紹了C#調(diào)用C動態(tài)鏈接庫的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-01-01基于C#實現(xiàn)自定義計算的Excel數(shù)據(jù)透視表
數(shù)據(jù)透視表(Pivot?Table)是一種數(shù)據(jù)分析工具,通常用于對大量數(shù)據(jù)進行匯總、分析和展示,本文主要介紹了C#實現(xiàn)自定義計算的Excel數(shù)據(jù)透視表的相關知識,感興趣的可以了解下2023-12-12