基于WPF實(shí)現(xiàn)步驟控件的示例代碼
WPF 實(shí)現(xiàn)步驟控件
框架使用.NET40
;
Visual Studio 2019
;
Step
繼承 ItemsControl
使用 Grid
嵌套 ProgressBar
和 ItemsPresenter
.
ProgressBar
用來當(dāng)作步驟后面的線條,寬等于控件的(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
增加兩個(gè)屬性 Index
用來記錄當(dāng)前是步驟 與 State
記錄狀態(tài) (等待中、進(jìn)行中、已完成)。
因?yàn)槔^承了 ContentControl
所以可以在使用時(shí)指定 Content
顯示內(nèi)容,在每個(gè)步驟下方顯示。
實(shí)現(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> ????????///?正在進(jìn)行中 ????????///?</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="填寫賬號(hào)"/> ????????????????????<wd:StepItem?Content="身份驗(yàn)證"/> ????????????????????<wd:StepItem?Content="設(shè)置新密碼"/> ????????????????????<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實(shí)現(xiàn)步驟控件的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于WPF步驟控件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#調(diào)用C動(dòng)態(tài)鏈接庫的實(shí)現(xiàn)
動(dòng)態(tài)鏈接庫是不能直接執(zhí)行的,也不能接收消息,它只是一個(gè)獨(dú)立的文件,本文主要介紹了C#調(diào)用C動(dòng)態(tài)鏈接庫的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01C#基礎(chǔ)知識(shí)之base關(guān)鍵字介紹
本文主要介紹base關(guān)鍵字的使用方法,base關(guān)鍵字可以調(diào)用基類重寫的方法,可以調(diào)用基類的構(gòu)造方法,還可以在EntityFramework中使用,下面一一介紹。2016-04-04C#影院售票系統(tǒng)畢業(yè)設(shè)計(jì)(4)
這篇文章主要介紹了C#影院售票系統(tǒng)畢業(yè)設(shè)計(jì),學(xué)習(xí)內(nèi)容是總結(jié)銷售信息的保存以及加載銷售信息,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-11-11C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量三
C#語言類型系統(tǒng)提出的一個(gè)核心概念裝箱(boxing)拆箱(unboxing)。裝箱和取消裝箱的概念是C#的類型系統(tǒng)的核心。它在“值類型”和“引用類型”之間的架起了一座橋梁,使得任何“值類型”的值都可以轉(zhuǎn)換為object類型的值,反過來轉(zhuǎn)換也可以。2015-10-10基于C#實(shí)現(xiàn)自定義計(jì)算的Excel數(shù)據(jù)透視表
數(shù)據(jù)透視表(Pivot?Table)是一種數(shù)據(jù)分析工具,通常用于對(duì)大量數(shù)據(jù)進(jìn)行匯總、分析和展示,本文主要介紹了C#實(shí)現(xiàn)自定義計(jì)算的Excel數(shù)據(jù)透視表的相關(guān)知識(shí),感興趣的可以了解下2023-12-12