-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
1,452 additions
and
3 deletions.
There are no files selected for viewing
88 changes: 88 additions & 0 deletions
88
dev/DevWinUI.Controls/Controls/StepBar/StepBar.Property.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
namespace DevWinUI; | ||
public partial class StepBar | ||
{ | ||
public StepStatus Status | ||
{ | ||
get => (StepStatus)GetValue(StatusProperty); | ||
set => SetValue(StatusProperty, value); | ||
} | ||
|
||
public static readonly DependencyProperty StatusProperty = | ||
DependencyProperty.Register(nameof(Status), typeof(StepStatus), typeof(StepBar), new PropertyMetadata(StepStatus.Info, OnStepStatusChanged)); | ||
|
||
private static void OnStepStatusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
var ctl = (StepBar)d; | ||
if (ctl != null) | ||
{ | ||
ctl.UpdateItems(); | ||
} | ||
} | ||
|
||
public int StepIndex | ||
{ | ||
get => (int)GetValue(StepIndexProperty); | ||
set | ||
{ | ||
if (ItemsCount > 0) | ||
{ | ||
int clampedValue = Math.Max(0, Math.Min(ItemsCount - 1, value)); | ||
SetValue(StepIndexProperty, clampedValue); | ||
} | ||
else | ||
{ | ||
SetValue(StepIndexProperty, value); | ||
} | ||
} | ||
} | ||
|
||
public static readonly DependencyProperty StepIndexProperty = | ||
DependencyProperty.Register(nameof(StepIndex), typeof(int), typeof(StepBar), new PropertyMetadata(0, OnStepIndexChanged)); | ||
|
||
private static void OnStepIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
var ctl = (StepBar)d; | ||
if (ctl != null) | ||
{ | ||
ctl.OnStepIndexChanged((int)e.NewValue); | ||
} | ||
} | ||
|
||
public Orientation Orientation | ||
{ | ||
get => (Orientation)GetValue(OrientationProperty); | ||
set => SetValue(OrientationProperty, value); | ||
} | ||
public static readonly DependencyProperty OrientationProperty = | ||
DependencyProperty.Register(nameof(Orientation), typeof(Orientation), typeof(StepBar), new PropertyMetadata(Orientation.Horizontal, OnOrientationChanged)); | ||
|
||
private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
var ctl = (StepBar)d; | ||
if (ctl != null) | ||
{ | ||
ctl.UpdateItemsPanel(); | ||
ctl.UpdateProgressBarSize(); | ||
ctl.OnStepIndexChanged(ctl.StepIndex); | ||
ctl.UpdateItems(); | ||
} | ||
} | ||
|
||
public StepBarHeaderDisplayMode HeaderDisplayMode | ||
{ | ||
get { return (StepBarHeaderDisplayMode)GetValue(HeaderDisplayModeProperty); } | ||
set { SetValue(HeaderDisplayModeProperty, value); } | ||
} | ||
|
||
public static readonly DependencyProperty HeaderDisplayModeProperty = | ||
DependencyProperty.Register(nameof(HeaderDisplayMode), typeof(StepBarHeaderDisplayMode), typeof(StepBar), new PropertyMetadata(StepBarHeaderDisplayMode.Bottom, OnHeaderDisplayModeChanged)); | ||
|
||
private static void OnHeaderDisplayModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
var ctl = (StepBar)d; | ||
if (ctl != null) | ||
{ | ||
ctl.UpdateHeaderDisplayMode(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
using Microsoft.UI.Xaml.Markup; | ||
|
||
namespace DevWinUI; | ||
|
||
[ContentProperty(Name = nameof(Items))] | ||
[TemplatePart(Name = ElementProgressBar, Type = typeof(ProgressBar))] | ||
public partial class StepBar : ItemsControl | ||
{ | ||
private const string ElementProgressBar = "PART_ProgressBar"; | ||
private const string ElementProgressBarBorder = "PART_ProgressBarBorder"; | ||
private const string ElementRootGridVertical = "PART_RootGridVertical"; | ||
|
||
private ProgressBar progressBar; | ||
private Border progressBarBorder; | ||
private Grid rootGridVertical; | ||
private int ItemsCount => Items.Count; | ||
public ControlTemplate? HorizontalTemplate { get; set; } | ||
public ControlTemplate? VerticalTemplate { get; set; } | ||
public Style? HorizontalItemContainerStyle { get; set; } | ||
public Style? VerticalItemContainerStyle { get; set; } | ||
|
||
private int _oriStepIndex = -1; | ||
private void UpdateTemplate() | ||
{ | ||
Template = Orientation switch | ||
{ | ||
Orientation.Horizontal => HorizontalTemplate, | ||
Orientation.Vertical => VerticalTemplate, | ||
_ => Template | ||
}; | ||
|
||
ItemContainerStyle = Orientation switch | ||
{ | ||
Orientation.Horizontal => HorizontalItemContainerStyle, | ||
Orientation.Vertical => VerticalItemContainerStyle, | ||
_ => ItemContainerStyle | ||
}; | ||
} | ||
public StepBar() | ||
{ | ||
if (Application.Current.Resources["StepBarHorizontalControlTemplate"] is ControlTemplate horizontalTemplate) | ||
HorizontalTemplate = horizontalTemplate; | ||
|
||
if (Application.Current.Resources["StepBarVerticalControlTemplate"] is ControlTemplate verticalTemplate) | ||
VerticalTemplate = verticalTemplate; | ||
|
||
if (Application.Current.Resources["StepBarItemHorizontalStyle"] is Style horizontalItemContainerStyle) | ||
HorizontalItemContainerStyle = horizontalItemContainerStyle; | ||
|
||
if (Application.Current.Resources["StepBarItemVerticalStyle"] is Style verticalItemContainerStyle) | ||
VerticalItemContainerStyle = verticalItemContainerStyle; | ||
} | ||
|
||
protected override void OnApplyTemplate() | ||
{ | ||
base.OnApplyTemplate(); | ||
progressBar = GetTemplateChild(ElementProgressBar) as ProgressBar; | ||
progressBarBorder = GetTemplateChild(ElementProgressBarBorder) as Border; | ||
rootGridVertical = GetTemplateChild(ElementRootGridVertical) as Grid; | ||
|
||
SetProgressBarMaximumValue(); | ||
UpdateItemsPanel(); | ||
UpdateHeaderDisplayMode(); | ||
UpdateProgressBarVisualStates(); | ||
SizeChanged -= OnSizeChanged; | ||
SizeChanged += OnSizeChanged; | ||
} | ||
private void OnSizeChanged(object sender, SizeChangedEventArgs e) | ||
{ | ||
UpdateItems(); | ||
} | ||
protected override void OnItemsChanged(object e) | ||
{ | ||
base.OnItemsChanged(e); | ||
UpdateItems(); | ||
} | ||
|
||
private void UpdateItemsPanel() | ||
{ | ||
UpdateTemplate(); | ||
|
||
if (Orientation == Orientation.Horizontal) | ||
{ | ||
ItemsPanel = (ItemsPanelTemplate)XamlReader.Load("<ItemsPanelTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><UniformGrid xmlns='using:DevWinUI' Rows='1'/></ItemsPanelTemplate>"); | ||
} | ||
else | ||
{ | ||
ItemsPanel = (ItemsPanelTemplate)XamlReader.Load("<ItemsPanelTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><UniformGrid xmlns='using:DevWinUI' Columns='1'/></ItemsPanelTemplate>"); | ||
} | ||
} | ||
|
||
private void UpdateHeaderDisplayMode() | ||
{ | ||
if (Orientation == Orientation.Horizontal) | ||
{ | ||
if (progressBar == null) | ||
{ | ||
return; | ||
} | ||
switch (HeaderDisplayMode) | ||
{ | ||
case StepBarHeaderDisplayMode.Top: | ||
progressBar.VerticalAlignment = VerticalAlignment.Bottom; | ||
progressBar.HorizontalAlignment = HorizontalAlignment.Center; | ||
progressBar.Margin = new Thickness(0, 0, 0, 20); | ||
break; | ||
case StepBarHeaderDisplayMode.Left: | ||
case StepBarHeaderDisplayMode.Right: | ||
case StepBarHeaderDisplayMode.Bottom: | ||
progressBar.VerticalAlignment = VerticalAlignment.Top; | ||
progressBar.HorizontalAlignment = HorizontalAlignment.Center; | ||
progressBar.Margin = new Thickness(0, 20, 0, 0); | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
if (rootGridVertical == null) | ||
{ | ||
return; | ||
} | ||
switch (HeaderDisplayMode) | ||
{ | ||
case StepBarHeaderDisplayMode.Top: | ||
case StepBarHeaderDisplayMode.Bottom: | ||
case StepBarHeaderDisplayMode.Right: | ||
rootGridVertical.FlowDirection = FlowDirection.LeftToRight; | ||
break; | ||
case StepBarHeaderDisplayMode.Left: | ||
rootGridVertical.FlowDirection = FlowDirection.RightToLeft; | ||
break; | ||
} | ||
} | ||
UpdateItems(); | ||
} | ||
|
||
private void SetProgressBarMaximumValue() | ||
{ | ||
if (progressBar != null) | ||
{ | ||
progressBar.Maximum = ItemsCount - 1; | ||
} | ||
} | ||
|
||
private void UpdateProgressBarSize() | ||
{ | ||
int colOrRowCount = ItemsCount; | ||
|
||
if (Orientation == Orientation.Horizontal) | ||
{ | ||
if (progressBar == null || colOrRowCount <= 0) | ||
{ | ||
return; | ||
} | ||
progressBar.Width = (colOrRowCount - 1) * (ActualWidth / colOrRowCount); | ||
} | ||
else | ||
{ | ||
if (progressBarBorder == null || colOrRowCount <= 0) | ||
{ | ||
return; | ||
} | ||
progressBarBorder.Height = (colOrRowCount - 1) * (ActualHeight / colOrRowCount); | ||
} | ||
} | ||
|
||
private void UpdateItems() | ||
{ | ||
int count = ItemsCount; | ||
if (count <= 0) | ||
{ | ||
return; | ||
} | ||
|
||
SetProgressBarMaximumValue(); | ||
SetProgressBarValueWithAnimation(StepIndex); | ||
|
||
for (int i = 0; i < count; i++) | ||
{ | ||
if (ItemContainerGenerator.ContainerFromIndex(i) is StepBarItem stepBarItem) | ||
{ | ||
stepBarItem.Index = i + 1; | ||
stepBarItem.Orientation = this.Orientation; | ||
stepBarItem.HeaderDisplayMode = this.HeaderDisplayMode; | ||
} | ||
} | ||
|
||
if (_oriStepIndex > 0) | ||
{ | ||
StepIndex = _oriStepIndex; | ||
_oriStepIndex = -1; | ||
} | ||
else | ||
{ | ||
OnStepIndexChanged(StepIndex); | ||
} | ||
|
||
UpdateProgressBarSize(); | ||
} | ||
|
||
private void OnStepIndexChanged(int stepIndex) | ||
{ | ||
if (progressBar == null) | ||
{ | ||
return; | ||
} | ||
|
||
if (stepIndex < 0) | ||
{ | ||
SetProgressBarValueWithAnimation(0); | ||
return; | ||
} | ||
|
||
for (int i = 0; i < stepIndex; i++) | ||
{ | ||
if (ItemContainerGenerator.ContainerFromIndex(i) is StepBarItem stepItemFinished) | ||
{ | ||
UpdateProgressBarVisualStates(); | ||
stepItemFinished.ProgressState = StepProgressState.Complete; | ||
stepItemFinished.Status = Status; | ||
} | ||
} | ||
|
||
for (int i = stepIndex + 1; i < ItemsCount; i++) | ||
{ | ||
if (ItemContainerGenerator.ContainerFromIndex(i) is StepBarItem stepItemFinished) | ||
{ | ||
UpdateProgressBarVisualStates(); | ||
stepItemFinished.ProgressState = StepProgressState.Waiting; | ||
stepItemFinished.Status = Status; | ||
} | ||
} | ||
|
||
if (ItemContainerGenerator.ContainerFromIndex(stepIndex) is StepBarItem stepItemSelected) | ||
{ | ||
UpdateProgressBarVisualStates(); | ||
stepItemSelected.ProgressState = StepProgressState.UnderWay; | ||
stepItemSelected.Status = Status; | ||
} | ||
SetProgressBarValueWithAnimation(StepIndex); | ||
} | ||
|
||
private void SetProgressBarValueWithAnimation(double toValue, int duration = 200) | ||
{ | ||
if (progressBar == null) | ||
{ | ||
return; | ||
} | ||
var horizontalAnimation = new DoubleAnimation | ||
{ | ||
From = progressBar.Value, | ||
To = toValue, | ||
Duration = new Duration(TimeSpan.FromMilliseconds(duration)), | ||
EnableDependentAnimation = true | ||
}; | ||
|
||
Storyboard.SetTarget(horizontalAnimation, progressBar); | ||
Storyboard.SetTargetProperty(horizontalAnimation, nameof(ProgressBar.Value)); | ||
|
||
var horizontalStoryboard = new Storyboard(); | ||
horizontalStoryboard.Children.Add(horizontalAnimation); | ||
horizontalStoryboard.Begin(); | ||
} | ||
|
||
private void UpdateProgressBarVisualStates() | ||
{ | ||
VisualStateManager.GoToState(this, Status.ToString(), true); | ||
} | ||
|
||
public void Next() => StepIndex++; | ||
public void Prev() => StepIndex--; | ||
} |
8 changes: 8 additions & 0 deletions
8
dev/DevWinUI.Controls/Controls/StepBar/StepBarHeaderDisplayMode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace DevWinUI; | ||
public enum StepBarHeaderDisplayMode | ||
{ | ||
Top, | ||
Bottom, | ||
Left, | ||
Right | ||
} |
Oops, something went wrong.