├── .github
└── workflows
│ └── nuget.yml
├── .gitignore
├── DropdownMenuControl
├── AssemblyInfo.cs
├── DropdownMenu.cs
├── DropdownMenuControl.csproj
├── DropdownMenuControl.csproj.user
└── Themes
│ └── Generic.xaml
├── HamburgerMenuControl
├── AssemblyInfo.cs
├── HamburgerMenu.cs
├── HamburgerMenuControl.csproj
├── HamburgerMenuControl.csproj.user
├── HamburgerMenuItem.cs
└── Themes
│ └── Generic.xaml
├── HighlightTextBlockControl
├── AssemblyInfo.cs
├── HighlightTextBlock.cs
├── HighlightTextBlockControl.csproj
├── HighlightTextBlockControl.csproj.user
└── Themes
│ └── Generic.xaml
├── HoldSubmitButtonControl
├── AssemblyInfo.cs
├── Converters
│ ├── DurationSecondsSubtractionConverter.cs
│ └── MultiplyConverter.cs
├── HoldSubmitButton.cs
├── HoldSubmitButtonControl.csproj
├── HoldSubmitButtonControl.csproj.user
└── Themes
│ └── Generic.xaml
├── LoadingSpinnerControl
├── AssemblyInfo.cs
├── Converters
│ └── DiameterAndThicknessToStrokeDashArrayConverter.cs
├── LoadingSpinner.cs
├── LoadingSpinnerControl.csproj
├── LoadingSpinnerControl.csproj.user
└── Themes
│ └── Generic.xaml
├── ModalControl
├── AssemblyInfo.cs
├── Modal.cs
├── ModalControl.csproj
├── ModalControl.csproj.user
└── Themes
│ └── Generic.xaml
├── PlaceholderTextBox
├── AssemblyInfo.cs
├── PlaceholderTextBox.csproj
├── PlaceholderTextBox.csproj.user
├── PlaceholderTextBoxControl.cs
└── Themes
│ └── Generic.xaml
├── UIWorkshops.Demo
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── UIWorkshops.Demos.csproj
├── UIWorkshops.Demos.csproj.user
└── Windows
│ ├── DropdownMenuDemoWindow.xaml
│ ├── DropdownMenuDemoWindow.xaml.cs
│ ├── HamburgerMenuDemoWindow.xaml
│ ├── HamburgerMenuDemoWindow.xaml.cs
│ ├── HighlightTextBlockDemoWindow.xaml
│ ├── HighlightTextBlockDemoWindow.xaml.cs
│ ├── HoldSubmitButtonDemoWindow.xaml
│ ├── HoldSubmitButtonDemoWindow.xaml.cs
│ ├── LoadingSpinnerDemoWindow.xaml
│ ├── LoadingSpinnerDemoWindow.xaml.cs
│ ├── ModalDemoWindow.xaml
│ ├── ModalDemoWindow.xaml.cs
│ ├── PlaceholderTextBoxDemoWindow.xaml
│ └── PlaceholderTextBoxDemoWindow.xaml.cs
└── UIWorkshops.sln
/.github/workflows/nuget.yml:
--------------------------------------------------------------------------------
1 | name: "Deploy Loading Spinner to NuGet"
2 |
3 | on:
4 | push:
5 | branches:
6 | - 'release/loading-spinner'
7 |
8 | env:
9 | BUILD_CONFIGURATION: Release
10 | PACKAGE_OUTPUT_DIRECTORY: ${{ github.workspace }}\output
11 | NUGET_SOURCE_URL: "https://api.nuget.org/v3/index.json"
12 | PACK_OPTIONS: "--no-restore --no-build --include-symbols --include-source"
13 |
14 | jobs:
15 | deploy:
16 | runs-on: windows-latest
17 | steps:
18 | # Setup
19 | - uses: actions/checkout@v2
20 |
21 | - name: Setup .NET Core
22 | uses: actions/setup-dotnet@v1
23 | with:
24 | dotnet-version: "3.1.x"
25 |
26 | # Fix annoying packages not being found
27 | - name: Clean
28 | run: dotnet clean -c ${{ env.BUILD_CONFIGURATION }} && dotnet nuget locals all --clear
29 |
30 | # .NET
31 | - name: Restore .NET packages
32 | run: dotnet restore
33 |
34 | - name: Build .NET projects
35 | run: dotnet build --no-restore -c ${{ env.BUILD_CONFIGURATION }}
36 |
37 | - name: "Pack Loading Spinner Control project"
38 | run: dotnet pack LoadingSpinnerControl -c ${{ env.BUILD_CONFIGURATION }} --output ${{ env.PACKAGE_OUTPUT_DIRECTORY }} ${{ env.PACK_OPTIONS }}
39 |
40 | - name: "Push packages"
41 | run: dotnet nuget push ${{ env.PACKAGE_OUTPUT_DIRECTORY }}\*.nupkg -k ${{ secrets.NUGET_AUTH_TOKEN }} -s ${{ env.NUGET_SOURCE_URL }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | obj/
2 | bin/
3 | .vs/
--------------------------------------------------------------------------------
/DropdownMenuControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/DropdownMenuControl/DropdownMenu.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Controls.Primitives;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 |
17 | namespace DropdownMenuControl
18 | {
19 | [TemplatePart(Name = PART_POPUP_NAME, Type = typeof(Popup))]
20 | [TemplatePart(Name = PART_TOGGLE_NAME, Type = typeof(CheckBox))]
21 | public class DropdownMenu : ContentControl
22 | {
23 | private const string PART_POPUP_NAME = "PART_Popup";
24 | private const string PART_TOGGLE_NAME = "PART_Toggle";
25 |
26 | private Popup _popup;
27 | private CheckBox _toggle;
28 |
29 | public static readonly DependencyProperty IsOpenProperty =
30 | DependencyProperty.Register("IsOpen", typeof(bool), typeof(DropdownMenu),
31 | new PropertyMetadata(false));
32 |
33 | public bool IsOpen
34 | {
35 | get { return (bool)GetValue(IsOpenProperty); }
36 | set { SetValue(IsOpenProperty, value); }
37 | }
38 |
39 | static DropdownMenu()
40 | {
41 | DefaultStyleKeyProperty.OverrideMetadata(typeof(DropdownMenu), new FrameworkPropertyMetadata(typeof(DropdownMenu)));
42 | }
43 |
44 | public override void OnApplyTemplate()
45 | {
46 | _popup = Template.FindName(PART_POPUP_NAME, this) as Popup;
47 | if (_popup != null)
48 | {
49 | _popup.Closed += Popup_Closed;
50 | }
51 |
52 | _toggle = Template.FindName(PART_TOGGLE_NAME, this) as CheckBox;
53 |
54 | base.OnApplyTemplate();
55 | }
56 |
57 | private void Popup_Closed(object sender, EventArgs e)
58 | {
59 | if (!_toggle.IsMouseOver)
60 | {
61 | IsOpen = false;
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/DropdownMenuControl/DropdownMenuControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 | DropdownMenu.WPF
10 | 1.0.0
11 | SingletonSean
12 | snupkg
13 | https://github.com/SingletonSean/wpf-ui-workshops
14 | https://github.com/SingletonSean/wpf-ui-workshops
15 | wpf custom dropdown menu item triple dot
16 |
17 | A custom, easy to use dropdown menu control for WPF applications.
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/DropdownMenuControl/DropdownMenuControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DropdownMenuControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
5 |
39 |
40 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/HamburgerMenu.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Animation;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 |
17 | namespace HamburgerMenuControl
18 | {
19 | public class HamburgerMenu : Control
20 | {
21 | public static readonly DependencyProperty IsOpenProperty =
22 | DependencyProperty.Register("IsOpen", typeof(bool), typeof(HamburgerMenu),
23 | new PropertyMetadata(false, OnIsOpenPropertyChanged));
24 |
25 | public bool IsOpen
26 | {
27 | get { return (bool)GetValue(IsOpenProperty); }
28 | set { SetValue(IsOpenProperty, value); }
29 | }
30 |
31 | public static readonly DependencyProperty OpenCloseDurationProperty =
32 | DependencyProperty.Register("OpenCloseDuration", typeof(Duration), typeof(HamburgerMenu),
33 | new PropertyMetadata(Duration.Automatic));
34 |
35 | public Duration OpenCloseDuration
36 | {
37 | get { return (Duration)GetValue(OpenCloseDurationProperty); }
38 | set { SetValue(OpenCloseDurationProperty, value); }
39 | }
40 |
41 | public static readonly DependencyProperty FallbackOpenWidthProperty =
42 | DependencyProperty.Register("FallbackOpenWidth", typeof(double), typeof(HamburgerMenu),
43 | new PropertyMetadata(100.0));
44 |
45 | public double FallbackOpenWidth
46 | {
47 | get { return (double)GetValue(FallbackOpenWidthProperty); }
48 | set { SetValue(FallbackOpenWidthProperty, value); }
49 | }
50 |
51 | public static readonly DependencyProperty ContentProperty =
52 | DependencyProperty.Register("Content", typeof(FrameworkElement), typeof(HamburgerMenu),
53 | new PropertyMetadata(null));
54 |
55 | public FrameworkElement Content
56 | {
57 | get { return (FrameworkElement)GetValue(ContentProperty); }
58 | set { SetValue(ContentProperty, value); }
59 | }
60 |
61 | static HamburgerMenu()
62 | {
63 | DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenu), new FrameworkPropertyMetadata(typeof(HamburgerMenu)));
64 | }
65 |
66 | public HamburgerMenu()
67 | {
68 | Width = 0;
69 | }
70 |
71 | private static void OnIsOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
72 | {
73 | if(d is HamburgerMenu hamburgerMenu)
74 | {
75 | hamburgerMenu.OnIsOpenPropertyChanged();
76 | }
77 | }
78 |
79 | private void OnIsOpenPropertyChanged()
80 | {
81 | if(IsOpen)
82 | {
83 | OpenMenuAnimated();
84 | }
85 | else
86 | {
87 | CloseMenuAnimated();
88 | }
89 | }
90 |
91 | private void OpenMenuAnimated()
92 | {
93 | double contentWidth = GetDesiredContentWidth();
94 |
95 | DoubleAnimation openingAnimation = new DoubleAnimation(contentWidth, OpenCloseDuration);
96 | BeginAnimation(WidthProperty, openingAnimation);
97 | }
98 |
99 | private double GetDesiredContentWidth()
100 | {
101 | if(Content == null)
102 | {
103 | return FallbackOpenWidth;
104 | }
105 |
106 | Content.Measure(new Size(MaxWidth, MaxHeight));
107 |
108 | return Content.DesiredSize.Width;
109 | }
110 |
111 | private void CloseMenuAnimated()
112 | {
113 | DoubleAnimation closingAnimation = new DoubleAnimation(0, OpenCloseDuration);
114 | BeginAnimation(WidthProperty, closingAnimation);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/HamburgerMenuControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/HamburgerMenuControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/HamburgerMenuItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 |
7 | namespace HamburgerMenuControl
8 | {
9 | public class HamburgerMenuItem : RadioButton
10 | {
11 | static HamburgerMenuItem()
12 | {
13 | DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenuItem), new FrameworkPropertyMetadata(typeof(HamburgerMenuItem)));
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/HamburgerMenuControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
5 |
19 |
20 |
35 |
36 |
--------------------------------------------------------------------------------
/HighlightTextBlockControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/HighlightTextBlockControl/HighlightTextBlock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace HighlightTextBlockControl
17 | {
18 | [TemplatePart(Name = TEXT_DISPLAY_PART_NAME, Type = typeof(TextBlock))]
19 | public class HighlightTextBlock : Control
20 | {
21 | private const string TEXT_DISPLAY_PART_NAME = "PART_TextDisplay";
22 |
23 | private TextBlock _displayTextBlock;
24 |
25 | public static readonly DependencyProperty HighlightTextProperty =
26 | DependencyProperty.Register("HighlightText", typeof(string), typeof(HighlightTextBlock),
27 | new PropertyMetadata(string.Empty, OnHighlightTextPropertyChanged));
28 |
29 | public string HighlightText
30 | {
31 | get { return (string)GetValue(HighlightTextProperty); }
32 | set { SetValue(HighlightTextProperty, value); }
33 | }
34 |
35 | public static readonly DependencyProperty TextProperty =
36 | TextBlock.TextProperty.AddOwner(typeof(HighlightTextBlock),
37 | new PropertyMetadata(string.Empty, OnHighlightTextPropertyChanged));
38 |
39 | public string Text
40 | {
41 | get { return (string)GetValue(TextProperty); }
42 | set { SetValue(TextProperty, value); }
43 | }
44 |
45 | public static readonly DependencyProperty HighlightRunStyleProperty =
46 | DependencyProperty.Register("HighlightRunStyle", typeof(Style), typeof(HighlightTextBlock),
47 | new PropertyMetadata(CreateDefaultHighlightRunStyle()));
48 |
49 | private static object CreateDefaultHighlightRunStyle()
50 | {
51 | Style style = new Style(typeof(Run));
52 | style.Setters.Add(new Setter(Run.BackgroundProperty, Brushes.Yellow));
53 |
54 | return style;
55 | }
56 |
57 | public Style HighlightRunStyle
58 | {
59 | get { return (Style)GetValue(HighlightRunStyleProperty); }
60 | set { SetValue(HighlightRunStyleProperty, value); }
61 | }
62 |
63 | static HighlightTextBlock()
64 | {
65 | DefaultStyleKeyProperty.OverrideMetadata(typeof(HighlightTextBlock), new FrameworkPropertyMetadata(typeof(HighlightTextBlock)));
66 | }
67 |
68 | public override void OnApplyTemplate()
69 | {
70 | _displayTextBlock = Template.FindName(TEXT_DISPLAY_PART_NAME, this) as TextBlock;
71 | UpdateHighlightDisplay();
72 |
73 | base.OnApplyTemplate();
74 | }
75 |
76 | private static void OnHighlightTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
77 | {
78 | if(d is HighlightTextBlock highlightTextBlock)
79 | {
80 | highlightTextBlock.UpdateHighlightDisplay();
81 | }
82 | }
83 |
84 | private void UpdateHighlightDisplay()
85 | {
86 | if(_displayTextBlock != null)
87 | {
88 | _displayTextBlock.Inlines.Clear();
89 |
90 | int highlightTextLength = HighlightText.Length;
91 | if(highlightTextLength == 0)
92 | {
93 | _displayTextBlock.Text = Text;
94 | }
95 | else
96 | {
97 | for (int i = 0; i < Text.Length; i++)
98 | {
99 | if(i + highlightTextLength > Text.Length)
100 | {
101 | _displayTextBlock.Inlines.Add(new Run(Text.Substring(i)));
102 | break;
103 | }
104 |
105 | int nextHighlightTextIndex = Text.IndexOf(HighlightText, i);
106 | if(nextHighlightTextIndex == -1)
107 | {
108 | _displayTextBlock.Inlines.Add(new Run(Text.Substring(i)));
109 | break;
110 | }
111 |
112 | _displayTextBlock.Inlines.Add(new Run(Text.Substring(i, nextHighlightTextIndex - i)));
113 | _displayTextBlock.Inlines.Add(CreateHighlightedRun(HighlightText));
114 |
115 | i = nextHighlightTextIndex + highlightTextLength - 1;
116 | }
117 | }
118 | }
119 | }
120 |
121 | private Run CreateHighlightedRun(string text)
122 | {
123 | return new Run(text)
124 | {
125 | Style = HighlightRunStyle
126 | };
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/HighlightTextBlockControl/HighlightTextBlockControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HighlightTextBlockControl/HighlightTextBlockControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HighlightTextBlockControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
5 |
14 |
15 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/Converters/DurationSecondsSubtractionConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Data;
7 |
8 | namespace HoldSubmitButtonControl.Converters
9 | {
10 | public class DurationSecondsSubtractionConverter : IValueConverter
11 | {
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | if(value is Duration duration && double.TryParse(parameter.ToString(), out double seconds))
15 | {
16 | return duration.Subtract(TimeSpan.FromSeconds(seconds));
17 | }
18 |
19 | return value;
20 | }
21 |
22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
23 | {
24 | throw new NotImplementedException();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/Converters/MultiplyConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Windows.Data;
6 |
7 | namespace HoldSubmitButtonControl.Converters
8 | {
9 | public class MultiplyConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | return double.TryParse(value.ToString(), out double num1) &&
14 | double.TryParse(parameter.ToString(), out double num2) ?
15 | num1 * num2 : 0;
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | throw new NotImplementedException();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/HoldSubmitButton.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 |
17 | namespace HoldSubmitButtonControl
18 | {
19 | public class HoldSubmitButton : Button
20 | {
21 | private CancellationTokenSource _cancellationTokenSource;
22 |
23 | public static readonly DependencyProperty HoldDurationProperty =
24 | DependencyProperty.Register("HoldDuration", typeof(Duration), typeof(HoldSubmitButton),
25 | new PropertyMetadata(Duration.Automatic, null, CoerceHoldDuration));
26 |
27 | private static object CoerceHoldDuration(DependencyObject d, object baseValue)
28 | {
29 | if(baseValue is Duration duration && duration.TimeSpan.TotalSeconds >= 0.5)
30 | {
31 | return baseValue;
32 | }
33 |
34 | return new Duration(TimeSpan.FromSeconds(0.5));
35 | }
36 |
37 | public Duration HoldDuration
38 | {
39 | get { return (Duration)GetValue(HoldDurationProperty); }
40 | set { SetValue(HoldDurationProperty, value); }
41 | }
42 |
43 | public static readonly RoutedEvent HoldCompletedEvent =
44 | EventManager.RegisterRoutedEvent(nameof(HoldCompleted), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(HoldSubmitButton));
45 |
46 | public event RoutedEventHandler HoldCompleted
47 | {
48 | add => AddHandler(HoldCompletedEvent, value);
49 | remove => RemoveHandler(HoldCompletedEvent, value);
50 | }
51 |
52 | public static readonly RoutedEvent HoldCancelledEvent =
53 | EventManager.RegisterRoutedEvent(nameof(HoldCancelled), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(HoldSubmitButton));
54 |
55 | public event RoutedEventHandler HoldCancelled
56 | {
57 | add => AddHandler(HoldCancelledEvent, value);
58 | remove => RemoveHandler(HoldCancelledEvent, value);
59 | }
60 |
61 | static HoldSubmitButton()
62 | {
63 | DefaultStyleKeyProperty.OverrideMetadata(typeof(HoldSubmitButton), new FrameworkPropertyMetadata(typeof(HoldSubmitButton)));
64 | }
65 |
66 | protected override async void OnMouseLeftButtonDown(MouseButtonEventArgs e)
67 | {
68 | _cancellationTokenSource = new CancellationTokenSource();
69 |
70 | try
71 | {
72 | await Task.Delay((int)HoldDuration.TimeSpan.TotalMilliseconds, _cancellationTokenSource.Token);
73 | base.OnClick();
74 |
75 | RaiseEvent(new RoutedEventArgs(HoldCompletedEvent));
76 | }
77 | catch (TaskCanceledException)
78 | {
79 | RaiseEvent(new RoutedEventArgs(HoldCancelledEvent));
80 | }
81 |
82 | base.OnMouseLeftButtonDown(e);
83 | }
84 |
85 | protected override void OnClick() { }
86 |
87 | protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
88 | {
89 | CancelSubmit();
90 | base.OnMouseLeftButtonUp(e);
91 | }
92 |
93 | protected override void OnMouseLeave(MouseEventArgs e)
94 | {
95 | CancelSubmit();
96 | base.OnMouseLeave(e);
97 | }
98 |
99 | private void CancelSubmit()
100 | {
101 | if(_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested)
102 | {
103 | _cancellationTokenSource.Cancel();
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/HoldSubmitButtonControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/HoldSubmitButtonControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HoldSubmitButtonControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
6 |
125 |
126 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/Converters/DiameterAndThicknessToStrokeDashArrayConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Windows.Data;
6 | using System.Windows.Media;
7 |
8 | namespace LoadingSpinnerControl.Converters
9 | {
10 | public class DiameterAndThicknessToStrokeDashArrayConverter : IMultiValueConverter
11 | {
12 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | if(values.Length < 2 ||
15 | !double.TryParse(values[0].ToString(), out double diameter) ||
16 | !double.TryParse(values[1].ToString(), out double thickness))
17 | {
18 | return new DoubleCollection(new[] { 0.0 });
19 | }
20 |
21 | double circumference = Math.PI * diameter;
22 |
23 | double lineLength = circumference * 0.75;
24 | double gapLength = circumference - lineLength;
25 |
26 | return new DoubleCollection(new[] { lineLength / thickness, gapLength / thickness });
27 | }
28 |
29 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
30 | {
31 | throw new NotImplementedException();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/LoadingSpinner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace LoadingSpinnerControl
17 | {
18 | public class LoadingSpinner : Control
19 | {
20 | public static readonly DependencyProperty IsLoadingProperty =
21 | DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingSpinner),
22 | new PropertyMetadata(false));
23 |
24 | public bool IsLoading
25 | {
26 | get { return (bool)GetValue(IsLoadingProperty); }
27 | set { SetValue(IsLoadingProperty, value); }
28 | }
29 |
30 | public static readonly DependencyProperty DiameterProperty =
31 | DependencyProperty.Register("Diameter", typeof(double), typeof(LoadingSpinner),
32 | new PropertyMetadata(100.0));
33 |
34 | public double Diameter
35 | {
36 | get { return (double)GetValue(DiameterProperty); }
37 | set { SetValue(DiameterProperty, value); }
38 | }
39 |
40 | public static readonly DependencyProperty ThicknessProperty =
41 | DependencyProperty.Register("Thickness", typeof(double), typeof(LoadingSpinner),
42 | new PropertyMetadata(1.0));
43 |
44 | public double Thickness
45 | {
46 | get { return (double)GetValue(ThicknessProperty); }
47 | set { SetValue(ThicknessProperty, value); }
48 | }
49 |
50 | public static readonly DependencyProperty ColorProperty =
51 | DependencyProperty.Register("Color", typeof(Brush), typeof(LoadingSpinner),
52 | new PropertyMetadata(Brushes.Black));
53 |
54 | public Brush Color
55 | {
56 | get { return (Brush)GetValue(ColorProperty); }
57 | set { SetValue(ColorProperty, value); }
58 | }
59 |
60 | public static readonly DependencyProperty CapProperty =
61 | DependencyProperty.Register("Cap", typeof(PenLineCap), typeof(LoadingSpinner),
62 | new PropertyMetadata(PenLineCap.Flat));
63 |
64 | public PenLineCap Cap
65 | {
66 | get { return (PenLineCap)GetValue(CapProperty); }
67 | set { SetValue(CapProperty, value); }
68 | }
69 |
70 | static LoadingSpinner()
71 | {
72 | DefaultStyleKeyProperty.OverrideMetadata(typeof(LoadingSpinner), new FrameworkPropertyMetadata(typeof(LoadingSpinner)));
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/LoadingSpinnerControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 | LoadingSpinner.WPF
10 | 1.0.0
11 | SingletonSean
12 | snupkg
13 | https://github.com/SingletonSean/wpf-ui-workshops
14 | https://github.com/SingletonSean/wpf-ui-workshops
15 | wpf custom loading load spinner control
16 |
17 | A custom, easy to use loading spinner control for WPF applications.
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/LoadingSpinnerControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LoadingSpinnerControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
6 |
50 |
51 |
--------------------------------------------------------------------------------
/ModalControl/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/ModalControl/Modal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace ModalControl
17 | {
18 | public class Modal : ContentControl
19 | {
20 | public static readonly DependencyProperty IsOpenProperty =
21 | DependencyProperty.Register("IsOpen", typeof(bool), typeof(Modal),
22 | new PropertyMetadata(false));
23 |
24 | public bool IsOpen
25 | {
26 | get { return (bool)GetValue(IsOpenProperty); }
27 | set { SetValue(IsOpenProperty, value); }
28 | }
29 |
30 | static Modal()
31 | {
32 | DefaultStyleKeyProperty.OverrideMetadata(typeof(Modal), new FrameworkPropertyMetadata(typeof(Modal)));
33 | BackgroundProperty.OverrideMetadata(typeof(Modal), new FrameworkPropertyMetadata(CreateDefaultBackground()));
34 | }
35 |
36 | private static object CreateDefaultBackground()
37 | {
38 | return new SolidColorBrush(Colors.Black)
39 | {
40 | Opacity = 0.3
41 | };
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ModalControl/ModalControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 | SimpleModal.WPF
10 | 1.0.0
11 | SingletonSean
12 | snupkg
13 | https://github.com/SingletonSean/wpf-ui-workshops
14 | https://github.com/SingletonSean/wpf-ui-workshops
15 | wpf custom modal popup control
16 |
17 | A custom, easy to use modal control for WPF applications.
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ModalControl/ModalControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ModalControl/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
5 |
41 |
42 |
--------------------------------------------------------------------------------
/PlaceholderTextBox/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/PlaceholderTextBox/PlaceholderTextBox.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PlaceholderTextBox/PlaceholderTextBox.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PlaceholderTextBox/PlaceholderTextBoxControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace PlaceholderTextBox
17 | {
18 | public class PlaceholderTextBoxControl : TextBox
19 | {
20 | public static readonly DependencyProperty IsEmptyProperty =
21 | DependencyProperty.Register("IsEmpty", typeof(bool), typeof(PlaceholderTextBoxControl),
22 | new PropertyMetadata(false));
23 |
24 | public bool IsEmpty
25 | {
26 | get { return (bool)GetValue(IsEmptyProperty); }
27 | private set { SetValue(IsEmptyProperty, value); }
28 | }
29 |
30 | static PlaceholderTextBoxControl()
31 | {
32 | DefaultStyleKeyProperty.OverrideMetadata(typeof(PlaceholderTextBoxControl), new FrameworkPropertyMetadata(typeof(PlaceholderTextBoxControl)));
33 | }
34 |
35 | protected override void OnInitialized(EventArgs e)
36 | {
37 | UpdateIsEmpty();
38 | base.OnInitialized(e);
39 | }
40 |
41 | protected override void OnTextChanged(TextChangedEventArgs e)
42 | {
43 | UpdateIsEmpty();
44 | base.OnTextChanged(e);
45 | }
46 |
47 | private void UpdateIsEmpty()
48 | {
49 | IsEmpty = string.IsNullOrEmpty(Text);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/PlaceholderTextBox/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
5 |
33 |
34 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using UIWorkshops.Demos.Windows;
3 |
4 | namespace UIWorkshops.Demos
5 | {
6 | public partial class App : Application
7 | {
8 | protected override void OnStartup(StartupEventArgs e)
9 | {
10 | MainWindow = new DropdownMenuDemoWindow();
11 | MainWindow.Show();
12 |
13 | base.OnStartup(e);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/UIWorkshops.Demos.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | netcoreapp3.1
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/UIWorkshops.Demos.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Designer
7 |
8 |
9 |
10 |
11 | Code
12 |
13 |
14 | Code
15 |
16 |
17 | Code
18 |
19 |
20 |
21 |
22 | Designer
23 |
24 |
25 | Designer
26 |
27 |
28 | Designer
29 |
30 |
31 | Designer
32 |
33 |
34 | Designer
35 |
36 |
37 | Designer
38 |
39 |
40 | Designer
41 |
42 |
43 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/DropdownMenuDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
89 |
90 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/DropdownMenuDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Windows;
3 |
4 | namespace UIWorkshops.Demos.Windows
5 | {
6 | ///
7 | /// Interaction logic for DropdownMenuDemoWindow.xaml
8 | ///
9 | public partial class DropdownMenuDemoWindow : Window
10 | {
11 | public DropdownMenuDemoWindow()
12 | {
13 | InitializeComponent();
14 |
15 | lvNames.ItemsSource = new List()
16 | {
17 | "Joe",
18 | "Sean",
19 | "Mary"
20 | };
21 | }
22 |
23 | private void OnEditClick(object sender, RoutedEventArgs e)
24 | {
25 |
26 | }
27 |
28 | private void OnDeleteClick(object sender, RoutedEventArgs e)
29 | {
30 |
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HamburgerMenuDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
67 |
68 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HamburgerMenuDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.Windows.Navigation;
12 | using System.Windows.Shapes;
13 |
14 | namespace UIWorkshops.Demos.Windows
15 | {
16 | public partial class HamburgerMenuDemoWindow : Window
17 | {
18 | public HamburgerMenuDemoWindow()
19 | {
20 | InitializeComponent();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HighlightTextBlockDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
27 |
28 |
29 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HighlightTextBlockDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Shapes;
13 |
14 | namespace UIWorkshops.Demos.Windows
15 | {
16 | public partial class HighlightTextBlockDemoWindow : Window
17 | {
18 | public HighlightTextBlockDemoWindow()
19 | {
20 | InitializeComponent();
21 |
22 | lvItems.ItemsSource = new ObservableCollection()
23 | {
24 | "Hello world!",
25 | "My name is",
26 | "SingletonSean",
27 | "and my cat",
28 | "is meowing at me while I write this."
29 | };
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HoldSubmitButtonDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/HoldSubmitButtonDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.Windows.Shapes;
12 |
13 | namespace UIWorkshops.Demos.Windows
14 | {
15 | ///
16 | /// Interaction logic for HoldSubmitButtonDemoWindow.xaml
17 | ///
18 | public partial class HoldSubmitButtonDemoWindow : Window
19 | {
20 | public HoldSubmitButtonDemoWindow()
21 | {
22 | InitializeComponent();
23 | }
24 |
25 | private void HoldSubmitButton_Click(object sender, RoutedEventArgs e)
26 | {
27 | MessageBox.Show("Thanks for holding me.");
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/LoadingSpinnerDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/LoadingSpinnerDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.Windows.Shapes;
12 |
13 | namespace UIWorkshops.Demos.Windows
14 | {
15 | ///
16 | /// Interaction logic for LoadingSpinnerDemoWindow.xaml
17 | ///
18 | public partial class LoadingSpinnerDemoWindow : Window
19 | {
20 | public LoadingSpinnerDemoWindow()
21 | {
22 | InitializeComponent();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/ModalDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/ModalDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.Windows.Shapes;
12 |
13 | namespace UIWorkshops.Demos.Windows
14 | {
15 | public partial class ModalDemoWindow : Window
16 | {
17 | public ModalDemoWindow()
18 | {
19 | InitializeComponent();
20 | }
21 |
22 | private void OnShowModalClick(object sender, RoutedEventArgs e)
23 | {
24 | modal.IsOpen = true;
25 | }
26 |
27 | private void OnCloseModalClick(object sender, RoutedEventArgs e)
28 | {
29 | modal.IsOpen = false;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/PlaceholderTextBoxDemoWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/UIWorkshops.Demo/Windows/PlaceholderTextBoxDemoWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.Windows.Shapes;
12 |
13 | namespace UIWorkshops.Demos.Windows
14 | {
15 | ///
16 | /// Interaction logic for PlaceholderTextBoxDemoWindow.xaml
17 | ///
18 | public partial class PlaceholderTextBoxDemoWindow : Window
19 | {
20 | public PlaceholderTextBoxDemoWindow()
21 | {
22 | InitializeComponent();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/UIWorkshops.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30503.244
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UIWorkshops.Demos", "UIWorkshops.Demo\UIWorkshops.Demos.csproj", "{89CA86C9-8117-4934-A660-BA46D4227428}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HighlightTextBlockControl", "HighlightTextBlockControl\HighlightTextBlockControl.csproj", "{C147DADD-8B08-46ED-8A0C-5E0DF282CBD7}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HoldSubmitButtonControl", "HoldSubmitButtonControl\HoldSubmitButtonControl.csproj", "{2E852E49-CA74-4B32-8394-BF79D7F683C1}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoadingSpinnerControl", "LoadingSpinnerControl\LoadingSpinnerControl.csproj", "{4953D402-A7E2-4613-9F17-61E624E276ED}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaceholderTextBox", "PlaceholderTextBox\PlaceholderTextBox.csproj", "{145AB479-39AC-4C7E-AB17-0C59E444D0D9}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModalControl", "ModalControl\ModalControl.csproj", "{259FF005-EA2C-412C-91F8-E4614E64AAF3}"
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HamburgerMenuControl", "HamburgerMenuControl\HamburgerMenuControl.csproj", "{A9D3AF2E-0D73-4A01-A3F3-EA8C59EC56E3}"
19 | EndProject
20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropdownMenuControl", "DropdownMenuControl\DropdownMenuControl.csproj", "{5A570EBE-509D-4895-8FA6-9800846A13C6}"
21 | EndProject
22 | Global
23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 | Debug|Any CPU = Debug|Any CPU
25 | Release|Any CPU = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
28 | {89CA86C9-8117-4934-A660-BA46D4227428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {89CA86C9-8117-4934-A660-BA46D4227428}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {89CA86C9-8117-4934-A660-BA46D4227428}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {89CA86C9-8117-4934-A660-BA46D4227428}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {C147DADD-8B08-46ED-8A0C-5E0DF282CBD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {C147DADD-8B08-46ED-8A0C-5E0DF282CBD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {C147DADD-8B08-46ED-8A0C-5E0DF282CBD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {C147DADD-8B08-46ED-8A0C-5E0DF282CBD7}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {2E852E49-CA74-4B32-8394-BF79D7F683C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {2E852E49-CA74-4B32-8394-BF79D7F683C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {2E852E49-CA74-4B32-8394-BF79D7F683C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {2E852E49-CA74-4B32-8394-BF79D7F683C1}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {4953D402-A7E2-4613-9F17-61E624E276ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {4953D402-A7E2-4613-9F17-61E624E276ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {4953D402-A7E2-4613-9F17-61E624E276ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {4953D402-A7E2-4613-9F17-61E624E276ED}.Release|Any CPU.Build.0 = Release|Any CPU
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | GlobalSection(ExtensibilityGlobals) = postSolution
49 | SolutionGuid = {130CAE23-AE17-42CF-975E-1EBF94968A30}
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------