Skip to content

Commit 7e11b24

Browse files
authored
Merge pull request #739 from ButchersBoy/progress-buttons
WIP - Progress Buttons
2 parents f1ed10c + c71f85f commit 7e11b24

11 files changed

+491
-81
lines changed

MainDemo.Wpf/Buttons.xaml

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:system="clr-namespace:System;assembly=mscorlib"
77
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
8+
xmlns:materialDesignConverters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf"
89
xmlns:wpfExample="clr-namespace:MaterialDesignColors.WpfExample"
910
xmlns:domain="clr-namespace:MaterialDesignDemo.Domain"
1011
mc:Ignorable="d"
@@ -20,6 +21,8 @@
2021
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
2122
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml" />
2223
</ResourceDictionary.MergedDictionaries>
24+
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
25+
<materialDesignConverters:BooleanToVisibilityConverter x:Key="InvertedBooleanToVisibilityConverter" TrueValue="Collapsed" FalseValue="Visible" />
2326
</ResourceDictionary>
2427
</UserControl.Resources>
2528
<Grid VerticalAlignment="Top">
@@ -32,6 +35,8 @@
3235
<RowDefinition Height="Auto" />
3336
<RowDefinition Height="Auto" />
3437
<RowDefinition Height="Auto" />
38+
<RowDefinition Height="Auto" />
39+
<RowDefinition Height="Auto" />
3540
</Grid.RowDefinitions>
3641
<TextBlock Style="{StaticResource MaterialDesignHeadlineTextBlock}">Buttons</TextBlock>
3742
<Grid Grid.Row="1" >
@@ -212,10 +217,87 @@
212217
<Button Style="{StaticResource MaterialDesignFlatButton}" Click="ButtonBase_OnClick" ToolTip="MaterialDesignFlatButton" Margin="200 0 0 0">ACCEPT</Button>
213218
<Button Style="{StaticResource MaterialDesignFlatButton}" ToolTip="MaterialDesignFlatButton">CANCEL</Button>
214219
</StackPanel>
215-
216220
<Border Margin="0 16 0 0" BorderThickness="0 1 0 0" BorderBrush="{DynamicResource MaterialDesignDivider}" Grid.Row="4" />
217-
<TextBlock Margin="0 32 0 24" Grid.Row="4" Style="{StaticResource MaterialDesignHeadlineTextBlock}">Toggles</TextBlock>
218-
<Grid Grid.Row="5">
221+
222+
<TextBlock Style="{StaticResource MaterialDesignHeadlineTextBlock}"
223+
Grid.Row="5" Margin="0 12 0 12">Buttons - With Progress</TextBlock>
224+
<StackPanel Grid.Row="6" Orientation="Horizontal">
225+
<Grid Width="124">
226+
<!-- raised button with progress, useful to auto dismiss/accept something -->
227+
<Button Command="{Binding DismissComand}"
228+
Style="{StaticResource MaterialDesignRaisedButton}"
229+
HorizontalAlignment="Left"
230+
materialDesign:ButtonProgressAssist.Value="{Binding DismissButtonProgress}"
231+
Visibility="{Binding ShowDismissButton, Converter={StaticResource BooleanToVisibilityConverter}}">
232+
<StackPanel Orientation="Horizontal">
233+
<TextBlock>DISMISS</TextBlock>
234+
<materialDesign:PackIcon Margin="4 .5 0 0" Kind="Close" />
235+
</StackPanel>
236+
</Button>
237+
<TextBlock Text="{Binding DemoRestartCountdownText}"
238+
VerticalAlignment="Center"
239+
Visibility="{Binding ShowDismissButton, Converter={StaticResource InvertedBooleanToVisibilityConverter}}"
240+
/>
241+
</Grid>
242+
243+
<!-- floating action button with progress -->
244+
<TextBlock Margin="24 0 0 0" VerticalAlignment="Center">Click Me:</TextBlock>
245+
<Button Style="{StaticResource MaterialDesignFloatingActionLightButton}" Margin="8 0 0 0"
246+
Command="{Binding SaveComand}"
247+
materialDesign:ButtonProgressAssist.IsIndicatorVisible="{Binding IsSaving}"
248+
materialDesign:ButtonProgressAssist.Value="{Binding SaveProgress}">
249+
250+
<!-- simple example of toggling/animating pack icon with a data trigger-->
251+
<materialDesign:PackIcon Height="24" Width="24">
252+
<materialDesign:PackIcon.Style>
253+
<Style TargetType="materialDesign:PackIcon" BasedOn="{StaticResource {x:Type materialDesign:PackIcon}}">
254+
<Setter Property="Kind" Value="CloudSync" />
255+
<Style.Triggers>
256+
<DataTrigger Binding="{Binding IsSaveComplete}" Value="True">
257+
<Setter Property="Kind" Value="Check" />
258+
<DataTrigger.EnterActions>
259+
<BeginStoryboard>
260+
<Storyboard>
261+
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.8" />
262+
</Storyboard>
263+
</BeginStoryboard>
264+
</DataTrigger.EnterActions>
265+
</DataTrigger>
266+
</Style.Triggers>
267+
</Style>
268+
</materialDesign:PackIcon.Style>
269+
</materialDesign:PackIcon>
270+
271+
</Button>
272+
273+
<TextBlock Margin="24 0 0 0" VerticalAlignment="Center">Variations:</TextBlock>
274+
<Button Style="{StaticResource MaterialDesignFloatingActionButton}" Margin="16 0 0 0"
275+
materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
276+
materialDesign:ButtonProgressAssist.Value="-1"
277+
materialDesign:ButtonProgressAssist.IsIndeterminate="True"
278+
Content="{materialDesign:PackIcon DotsHorizontal}" />
279+
<Button Style="{StaticResource MaterialDesignFloatingActionAccentButton}" Margin="16 0 0 0"
280+
materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
281+
materialDesign:ButtonProgressAssist.Value="50"
282+
Content="{materialDesign:PackIcon DotsHorizontal}" />
283+
<Button Style="{StaticResource MaterialDesignFloatingActionButton}" Margin="16 0 0 0"
284+
Background="#81d4fa"
285+
BorderBrush="#81d4fa"
286+
Foreground="#DD000000"
287+
materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
288+
materialDesign:ButtonProgressAssist.Value="25"
289+
materialDesign:ButtonProgressAssist.IndicatorForeground="#e65100"
290+
materialDesign:ButtonProgressAssist.IndicatorBackground="#ffcc80"
291+
Content="{materialDesign:PackIcon DotsHorizontal}" />
292+
<Button Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}" Margin="16 0 0 0"
293+
materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
294+
materialDesign:ButtonProgressAssist.Value="75"
295+
Content="{materialDesign:PackIcon DotsHorizontal}" />
296+
</StackPanel>
297+
<Border Margin="0 16 0 0" BorderThickness="0 1 0 0" BorderBrush="{DynamicResource MaterialDesignDivider}" Grid.Row="7" />
298+
299+
<TextBlock Margin="0 32 0 24" Grid.Row="7" Style="{StaticResource MaterialDesignHeadlineTextBlock}">Toggles</TextBlock>
300+
<Grid Grid.Row="8">
219301
<Grid.RowDefinitions>
220302
<RowDefinition Height="Auto" />
221303
<RowDefinition Height="Auto" />
@@ -373,9 +455,9 @@
373455
</ListBox>
374456
</Grid>
375457

376-
<Border Grid.Row="6" Margin="0 16 0 0" BorderThickness="0 1 0 0" BorderBrush="{DynamicResource MaterialDesignDivider}" />
377-
<TextBlock Margin="0 32 0 0" Grid.Row="6" Style="{StaticResource MaterialDesignHeadlineTextBlock}">Rating bar</TextBlock>
378-
<StackPanel Grid.Row="7" Margin="0 16 0 0" Orientation="Horizontal">
458+
<Border Grid.Row="9" Margin="0 16 0 0" BorderThickness="0 1 0 0" BorderBrush="{DynamicResource MaterialDesignDivider}" />
459+
<TextBlock Margin="0 32 0 0" Grid.Row="9" Style="{StaticResource MaterialDesignHeadlineTextBlock}">Rating bar</TextBlock>
460+
<StackPanel Grid.Row="10" Margin="0 16 0 0" Orientation="Horizontal">
379461
<materialDesign:RatingBar Value="3" x:Name="BasicRatingBar" />
380462
<TextBlock Text="{Binding ElementName=BasicRatingBar, Path=Value, StringFormat=Rating: {0}}" VerticalAlignment="Top" Margin="10,2,0,0" />
381463
<materialDesign:RatingBar x:Name="CustomRatingBar" Max="3" Value="2" Margin="24 0 0 0" Orientation="Vertical">

MainDemo.Wpf/ButtonsViewModel.cs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
using MaterialDesignColors.WpfExample.Domain;
2+
using System;
3+
using System.ComponentModel;
4+
using System.Threading;
5+
using System.Windows.Input;
6+
using System.Windows.Threading;
7+
8+
namespace MaterialDesignColors.WpfExample
9+
{
10+
public class ButtonsViewModel : INotifyPropertyChanged
11+
{
12+
private bool _showDismissButton;
13+
private double _dismissButtonProgress;
14+
private string _demoRestartCountdownText;
15+
16+
public ButtonsViewModel()
17+
{
18+
var autoStartingActionCountdownStart = DateTime.Now;
19+
var demoRestartCountdownComplete = DateTime.Now;
20+
var dismissRequested = false;
21+
DismissComand = new AnotherCommandImplementation(_ => dismissRequested = true);
22+
ShowDismissButton = true;
23+
24+
#region DISMISS button demo control
25+
//just some demo code for the DISMISS button...it's up to you to set
26+
//up the progress on the button as it would be with a progress bar.
27+
//and then hide the button, do whatever action you want to do
28+
new DispatcherTimer(
29+
TimeSpan.FromMilliseconds(100),
30+
DispatcherPriority.Normal,
31+
new EventHandler((o, e) =>
32+
{
33+
if (dismissRequested)
34+
{
35+
ShowDismissButton = false;
36+
dismissRequested = false;
37+
demoRestartCountdownComplete = DateTime.Now.AddSeconds(3);
38+
DismissButtonProgress = 0;
39+
}
40+
41+
if (ShowDismissButton)
42+
{
43+
var totalDuration = autoStartingActionCountdownStart.AddSeconds(5).Ticks - autoStartingActionCountdownStart.Ticks;
44+
var currentDuration = DateTime.Now.Ticks - autoStartingActionCountdownStart.Ticks;
45+
var autoCountdownPercentComplete = 100.0 / totalDuration * currentDuration;
46+
DismissButtonProgress = autoCountdownPercentComplete;
47+
48+
if (DismissButtonProgress >= 100)
49+
{
50+
demoRestartCountdownComplete = DateTime.Now.AddSeconds(3);
51+
ShowDismissButton = false;
52+
UpdateDemoRestartCountdownText(demoRestartCountdownComplete, out _);
53+
}
54+
}
55+
else
56+
{
57+
UpdateDemoRestartCountdownText(demoRestartCountdownComplete, out bool isComplete);
58+
if (isComplete)
59+
{
60+
autoStartingActionCountdownStart = DateTime.Now;
61+
ShowDismissButton = true;
62+
}
63+
}
64+
65+
}), Dispatcher.CurrentDispatcher);
66+
#endregion
67+
68+
//just some demo code for the SAVE button
69+
SaveComand = new AnotherCommandImplementation(_ =>
70+
{
71+
if (IsSaveComplete == true)
72+
{
73+
IsSaveComplete = false;
74+
return;
75+
}
76+
77+
if (SaveProgress != 0) return;
78+
79+
var started = DateTime.Now;
80+
IsSaving = true;
81+
82+
new DispatcherTimer(
83+
TimeSpan.FromMilliseconds(50),
84+
DispatcherPriority.Normal,
85+
new EventHandler((o, e) =>
86+
{
87+
var totalDuration = started.AddSeconds(3).Ticks - started.Ticks;
88+
var currentProgress = DateTime.Now.Ticks - started.Ticks;
89+
var currentProgressPercent = 100.0 / totalDuration * currentProgress;
90+
91+
SaveProgress = currentProgressPercent;
92+
93+
if (SaveProgress >= 100)
94+
{
95+
IsSaveComplete = true;
96+
IsSaving = false;
97+
SaveProgress = 0;
98+
((DispatcherTimer)o).Stop();
99+
}
100+
101+
}), Dispatcher.CurrentDispatcher);
102+
});
103+
}
104+
105+
#region Dismiss button demo
106+
107+
public ICommand DismissComand { get; }
108+
109+
public bool ShowDismissButton
110+
{
111+
get { return _showDismissButton; }
112+
set { this.MutateVerbose(ref _showDismissButton, value, RaisePropertyChanged()); }
113+
}
114+
115+
public double DismissButtonProgress
116+
{
117+
get { return _dismissButtonProgress; }
118+
set { this.MutateVerbose(ref _dismissButtonProgress, value, RaisePropertyChanged()); }
119+
}
120+
121+
public string DemoRestartCountdownText
122+
{
123+
get { return _demoRestartCountdownText; }
124+
private set { this.MutateVerbose(ref _demoRestartCountdownText, value, RaisePropertyChanged()); }
125+
}
126+
127+
private void UpdateDemoRestartCountdownText(DateTime endTime, out bool isComplete)
128+
{
129+
var span = endTime - DateTime.Now;
130+
var seconds = Math.Round(span.TotalSeconds < 0 ? 0 : span.TotalSeconds);
131+
DemoRestartCountdownText = "Demo in " + seconds;
132+
isComplete = seconds == 0;
133+
}
134+
135+
#endregion
136+
137+
#region floating Save button demo
138+
139+
public ICommand SaveComand { get; }
140+
141+
private bool _isSaving;
142+
public bool IsSaving
143+
{
144+
get { return _isSaving; }
145+
private set { this.MutateVerbose(ref _isSaving, value, RaisePropertyChanged()); }
146+
}
147+
148+
private bool _isSaveComplete;
149+
public bool IsSaveComplete
150+
{
151+
get { return _isSaveComplete; }
152+
private set { this.MutateVerbose(ref _isSaveComplete, value, RaisePropertyChanged()); }
153+
}
154+
155+
private double _saveProgress;
156+
public double SaveProgress
157+
{
158+
get { return _saveProgress; }
159+
private set { this.MutateVerbose(ref _saveProgress, value, RaisePropertyChanged()); }
160+
}
161+
162+
#endregion
163+
164+
public event PropertyChangedEventHandler PropertyChanged;
165+
166+
private Action<PropertyChangedEventArgs> RaisePropertyChanged()
167+
{
168+
return args => PropertyChanged?.Invoke(this, args);
169+
}
170+
}
171+
}

MainDemo.Wpf/Domain/MainWindowViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ public MainWindowViewModel()
3030
DocumentationLink.DemoPageLink<PaletteSelectorViewModel>("Demo View Model"),
3131
DocumentationLink.ApiLink<PaletteHelper>()
3232
}),
33-
new DemoItem("Buttons & Toggles", new Buttons(),
33+
new DemoItem("Buttons & Toggles", new Buttons { DataContext = new ButtonsViewModel() } ,
3434
new []
3535
{
3636
DocumentationLink.WikiLink("Button-Styles", "Buttons"),
37-
DocumentationLink.DemoPageLink<Buttons>(),
37+
DocumentationLink.DemoPageLink<Buttons>("Demo View"),
38+
DocumentationLink.DemoPageLink<ButtonsViewModel>("Demo View Model"),
3839
DocumentationLink.StyleLink("Button"),
3940
DocumentationLink.StyleLink("CheckBox"),
4041
DocumentationLink.StyleLink("PopupBox"),

MainDemo.Wpf/MaterialDesignDemo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<Compile Include="Buttons.xaml.cs">
7676
<DependentUpon>Buttons.xaml</DependentUpon>
7777
</Compile>
78+
<Compile Include="ButtonsViewModel.cs" />
7879
<Compile Include="Cards.xaml.cs">
7980
<DependentUpon>Cards.xaml</DependentUpon>
8081
</Compile>

0 commit comments

Comments
 (0)