From 854065dd997b563fa590f33cf4630eaef68bd3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:35:50 +0800 Subject: [PATCH 01/20] Create TimePickerExample --- .../ExampleViews/TimePickerExample.xaml | 33 +++++++++++++++++++ .../ExampleViews/TimePickerExample.xaml.cs | 15 +++++++++ .../Helpers/MenuEnum.cs | 1 + .../ViewModels/MainVM.cs | 3 ++ .../WPFDevelopers.Samples.Shared.projitems | 7 ++++ .../WPFDevelopers.SamplesCode.csproj | 4 +++ 6 files changed, 63 insertions(+) create mode 100644 src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml create mode 100644 src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml.cs diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml new file mode 100644 index 00000000..de40e003 --- /dev/null +++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml.cs new file mode 100644 index 00000000..35be815c --- /dev/null +++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/TimePickerExample.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace WPFDevelopers.Samples.ExampleViews +{ + /// + /// TimePickerExample.xaml 的交互逻辑 + /// + public partial class TimePickerExample : UserControl + { + public TimePickerExample() + { + InitializeComponent(); + } + } +} diff --git a/src/WPFDevelopers.Samples.Shared/Helpers/MenuEnum.cs b/src/WPFDevelopers.Samples.Shared/Helpers/MenuEnum.cs index 36e787f9..457063ab 100644 --- a/src/WPFDevelopers.Samples.Shared/Helpers/MenuEnum.cs +++ b/src/WPFDevelopers.Samples.Shared/Helpers/MenuEnum.cs @@ -78,6 +78,7 @@ public enum MenuEnum NumericBox, ColorPicker, IPEditBox, + TimePicker, VirtualizingWrapPanel, AcrylicBlur, TaskbarInfo diff --git a/src/WPFDevelopers.Samples.Shared/ViewModels/MainVM.cs b/src/WPFDevelopers.Samples.Shared/ViewModels/MainVM.cs index f4245a49..95e5ceaf 100644 --- a/src/WPFDevelopers.Samples.Shared/ViewModels/MainVM.cs +++ b/src/WPFDevelopers.Samples.Shared/ViewModels/MainVM.cs @@ -312,6 +312,9 @@ void MenuItemSelection(string _menuName) case MenuEnum.IPEditBox: ControlPanel = new IPEditBoxExample(); break; + case MenuEnum.TimePicker: + ControlPanel = new TimePickerExample(); + break; case MenuEnum.VirtualizingWrapPanel: ControlPanel = new VirtualizingWrapPanel(); new VirtualizingWrapPanelExample().MaskShowDialog(); diff --git a/src/WPFDevelopers.Samples.Shared/WPFDevelopers.Samples.Shared.projitems b/src/WPFDevelopers.Samples.Shared/WPFDevelopers.Samples.Shared.projitems index 48c0caa6..8739ef24 100644 --- a/src/WPFDevelopers.Samples.Shared/WPFDevelopers.Samples.Shared.projitems +++ b/src/WPFDevelopers.Samples.Shared/WPFDevelopers.Samples.Shared.projitems @@ -394,6 +394,9 @@ Code ThermometerExample.xaml + + TimePickerExample.xaml + Code TransformThumbExample.xaml @@ -868,6 +871,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/src/WPFDevelopers.SamplesCode/WPFDevelopers.SamplesCode.csproj b/src/WPFDevelopers.SamplesCode/WPFDevelopers.SamplesCode.csproj index 3021e36b..eaf45a4c 100644 --- a/src/WPFDevelopers.SamplesCode/WPFDevelopers.SamplesCode.csproj +++ b/src/WPFDevelopers.SamplesCode/WPFDevelopers.SamplesCode.csproj @@ -141,6 +141,7 @@ + @@ -476,5 +477,8 @@ ExampleViews\IPEditBoxExample.xaml + + ExampleViews\TimePickerExample.xaml + From 883ec4cc41406c70d187983ee2f1b021f224cb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:37:22 +0800 Subject: [PATCH 02/20] Create TimeSelectorListBox.cs --- .../TimePicker/TimeSelectorListBox.cs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorListBox.cs diff --git a/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorListBox.cs b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorListBox.cs new file mode 100644 index 00000000..e71a73b7 --- /dev/null +++ b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorListBox.cs @@ -0,0 +1,84 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using WPFDevelopers.Helpers; + +namespace WPFDevelopers.Controls +{ + public class TimeSelectorListBox : ListBox + { + private bool isFirst = true; + private double lastIndex = 4; + private ScrollViewer scrollViewer; + + public TimeSelectorListBox() + { + Loaded += TimeSelectorListBox_Loaded; + PreviewMouseWheel += ScrollListBox_PreviewMouseWheel; + } + + protected override bool IsItemItsOwnContainerOverride(object item) + { + return item is TimeSelectorItem; + } + + protected override DependencyObject GetContainerForItemOverride() + { + return new TimeSelectorItem(); + } + + private void ScrollListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + if (Items != null && Items.Count > 0) + { + var delta = e.Delta; + var itemCount = Items.Count; + var scrollCount = delta > 0 ? -1 : 1; + var newIndex = SelectedIndex + scrollCount; + if (newIndex < 4) + newIndex = 5; + else if (newIndex >= itemCount - 4) + newIndex = itemCount; + SelectedIndex = newIndex; + e.Handled = true; + } + } + + private void TimeSelectorListBox_Loaded(object sender, RoutedEventArgs e) + { + scrollViewer = ControlsHelper.FindVisualChild(this); + if (scrollViewer != null) + { + scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged; + scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged; + } + } + + private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) + { + var offset = e.VerticalOffset; + if (isFirst == false) + { + lastIndex = offset + 4; + } + else + { + lastIndex = offset == 0 ? 4 : offset + 4; + isFirst = false; + } + } + + protected override void OnSelectionChanged(SelectionChangedEventArgs e) + { + if (SelectedIndex != -1 && lastIndex != -1) + { + if (SelectedIndex <= 0) return; + var index = SelectedIndex - lastIndex; + var offset = scrollViewer.VerticalOffset + index; + scrollViewer.ScrollToVerticalOffset(offset); + } + + base.OnSelectionChanged(e); + } + } +} \ No newline at end of file From f4d57aa52ca25a271e380931db01cc6a9c9a3a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:37:37 +0800 Subject: [PATCH 03/20] Create TimeSelectorItem.cs --- .../Controls/TimePicker/TimeSelectorItem.cs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorItem.cs diff --git a/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorItem.cs b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorItem.cs new file mode 100644 index 00000000..3f89d364 --- /dev/null +++ b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelectorItem.cs @@ -0,0 +1,8 @@ +using System.Windows.Controls; + +namespace WPFDevelopers.Controls +{ + public class TimeSelectorItem : ListBoxItem + { + } +} From 1b77b3b5c5af5a7d9e01cc8a13c1c247d3a29294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:37:54 +0800 Subject: [PATCH 04/20] Create TimeSelector.cs --- .../Controls/TimePicker/TimeSelector.cs | 204 ++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelector.cs diff --git a/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelector.cs b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelector.cs new file mode 100644 index 00000000..3f1b8900 --- /dev/null +++ b/src/WPFDevelopers.Shared/Controls/TimePicker/TimeSelector.cs @@ -0,0 +1,204 @@ +using System; +using System.Linq; +using System.Windows; +using System.Windows.Controls; + +namespace WPFDevelopers.Controls +{ + [TemplatePart(Name = ListBoxHourTemplateName, Type = typeof(ListBox))] + [TemplatePart(Name = ListBoxMinuteTemplateName, Type = typeof(ListBox))] + [TemplatePart(Name = ListBoxSecondTemplateName, Type = typeof(ListBox))] + public class TimeSelector : Control + { + private const string ListBoxHourTemplateName = "PART_ListBoxHour"; + private const string ListBoxMinuteTemplateName = "PART_ListBoxMinute"; + private const string ListBoxSecondTemplateName = "PART_ListBoxSecond"; + + public static readonly RoutedEvent SelectedTimeChangedEvent = + EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Bubble, + typeof(RoutedPropertyChangedEventHandler), typeof(TimeSelector)); + + public static readonly DependencyProperty SelectedTimeProperty = + DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimeSelector), + new PropertyMetadata(null, OnSelectedTimeChanged)); + + public static readonly DependencyProperty ItemHeightProperty = + DependencyProperty.Register("ItemHeight", typeof(double), typeof(TimeSelector), new PropertyMetadata(0d)); + + public static readonly DependencyProperty SelectorMarginProperty = + DependencyProperty.Register("SelectorMargin", typeof(Thickness), typeof(TimeSelector), + new PropertyMetadata(new Thickness(0))); + + private int _hour, _minute, _second; + + private ListBox _listBoxHour, _listBoxMinute, _listBoxSecond; + + static TimeSelector() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TimeSelector), + new FrameworkPropertyMetadata(typeof(TimeSelector))); + } + + + public DateTime? SelectedTime + { + get => (DateTime?) GetValue(SelectedTimeProperty); + set => SetValue(SelectedTimeProperty, value); + } + + + public double ItemHeight + { + get => (double) GetValue(ItemHeightProperty); + set => SetValue(ItemHeightProperty, value); + } + + + public Thickness SelectorMargin + { + get => (Thickness) GetValue(SelectorMarginProperty); + set => SetValue(SelectorMarginProperty, value); + } + + + public event RoutedPropertyChangedEventHandler SelectedTimeChanged + { + add => AddHandler(SelectedTimeChangedEvent, value); + remove => RemoveHandler(SelectedTimeChangedEvent, value); + } + + public virtual void OnSelectedTimeChanged(DateTime? oldValue, DateTime? newValue) + { + var args = new RoutedPropertyChangedEventArgs(oldValue, newValue, SelectedTimeChangedEvent); + RaiseEvent(args); + } + + private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctrl = d as TimeSelector; + if (ctrl != null) + ctrl.OnSelectedTimeChanged((DateTime?) e.OldValue, (DateTime?) e.NewValue); + } + + + private double GetItemHeight(ListBox listBox) + { + if (listBox.Items.Count > 0) + { + var listBoxItem = listBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem; + if (listBoxItem != null) return listBoxItem.ActualHeight; + } + + return 0; + } + + private int GetFirstNonEmptyItemIndex(ListBox listBox) + { + for (var i = 0; i < listBox.Items.Count; i++) + { + var item = listBox.Items[i] as string; + if (!string.IsNullOrWhiteSpace(item)) + return i; + } + + return -1; + } + + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + var minuteSecondList = Enumerable.Range(0, 60).Select(num => num.ToString("D2")); + var emptyData = Enumerable.Repeat(string.Empty, 4); + var result = emptyData.Concat(minuteSecondList).Concat(emptyData); + _listBoxHour = GetTemplateChild(ListBoxHourTemplateName) as ListBox; + if (_listBoxHour != null) + { + var hours = Enumerable.Range(0, 24).Select(num => num.ToString("D2")); + _listBoxHour.ItemsSource = emptyData.Concat(hours).Concat(emptyData); + _listBoxHour.SelectionChanged -= ListBoxHour_SelectionChanged; + _listBoxHour.SelectionChanged += ListBoxHour_SelectionChanged; + _listBoxHour.Loaded += (sender, args) => + { + var h = GetItemHeight(_listBoxHour); + if (h <= 0) return; + ItemHeight = h; + Height = h * 10; + var YAxis = GetFirstNonEmptyItemIndex(_listBoxHour) * h; + SelectorMargin = new Thickness(0, YAxis, 0, 0); + }; + } + + _listBoxMinute = GetTemplateChild(ListBoxMinuteTemplateName) as ListBox; + if (_listBoxMinute != null) + { + _listBoxMinute.SelectionChanged -= ListBoxMinute_SelectionChanged; + _listBoxMinute.SelectionChanged += ListBoxMinute_SelectionChanged; + _listBoxMinute.ItemsSource = result; + } + + _listBoxSecond = GetTemplateChild(ListBoxSecondTemplateName) as ListBox; + if (_listBoxSecond != null) + { + _listBoxSecond.SelectionChanged -= ListBoxSecond_SelectionChanged; + _listBoxSecond.SelectionChanged += ListBoxSecond_SelectionChanged; + _listBoxSecond.ItemsSource = result; + } + } + + private void ListBoxSecond_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (string.IsNullOrWhiteSpace(_listBoxSecond.SelectedValue.ToString())) return; + _second = Convert.ToInt32(_listBoxSecond.SelectedValue.ToString()); + SetSelectedTime(); + } + + private void ListBoxMinute_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (string.IsNullOrWhiteSpace(_listBoxMinute.SelectedValue.ToString())) return; + _minute = Convert.ToInt32(_listBoxMinute.SelectedValue.ToString()); + SetSelectedTime(); + } + + private void ListBoxHour_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (string.IsNullOrWhiteSpace(_listBoxHour.SelectedValue.ToString())) return; + _hour = Convert.ToInt32(_listBoxHour.SelectedValue.ToString()); + SetSelectedTime(); + } + + private void SetSelectedTime() + { + var dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, _hour, _minute, + _second); + SelectedTime = dt; + } + + public void SetTime() + { + if (!SelectedTime.HasValue) + return; + _hour = SelectedTime.Value.Hour; + _minute = SelectedTime.Value.Minute; + _second = SelectedTime.Value.Second; + + _listBoxHour.SelectionChanged -= ListBoxHour_SelectionChanged; + var hour = _hour.ToString("D2"); + _listBoxHour.SelectedItem = hour; + _listBoxHour.SelectionChanged += ListBoxHour_SelectionChanged; + + _listBoxMinute.SelectionChanged -= ListBoxMinute_SelectionChanged; + var minute = _minute.ToString("D2"); + _listBoxMinute.SelectedItem = minute; + _listBoxMinute.SelectionChanged += ListBoxMinute_SelectionChanged; + + _listBoxSecond.SelectionChanged -= ListBoxSecond_SelectionChanged; + var second = _second.ToString("D2"); + _listBoxSecond.SelectedItem = second; + _listBoxSecond.SelectionChanged += ListBoxSecond_SelectionChanged; + + SetSelectedTime(); + } + } +} \ No newline at end of file From 0633fde7bca160badabb840e1b894a7e5d246bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:38:08 +0800 Subject: [PATCH 05/20] Create TimePicker.cs --- .../Controls/TimePicker/TimePicker.cs | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/WPFDevelopers.Shared/Controls/TimePicker/TimePicker.cs diff --git a/src/WPFDevelopers.Shared/Controls/TimePicker/TimePicker.cs b/src/WPFDevelopers.Shared/Controls/TimePicker/TimePicker.cs new file mode 100644 index 00000000..ff33b61b --- /dev/null +++ b/src/WPFDevelopers.Shared/Controls/TimePicker/TimePicker.cs @@ -0,0 +1,128 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; + +namespace WPFDevelopers.Controls +{ + [TemplatePart(Name = TimeSelectorTemplateName, Type = typeof(ListBox))] + [TemplatePart(Name = EditableTextBoxTemplateName, Type = typeof(TextBox))] + [TemplatePart(Name = PopupTemplateName, Type = typeof(Popup))] + public class TimePicker : Control + { + private const string TimeSelectorTemplateName = "PART_TimeSelector"; + private const string EditableTextBoxTemplateName = "PART_EditableTextBox"; + private const string PopupTemplateName = "PART_Popup"; + + public static readonly DependencyProperty SelectedTimeFormatProperty = + DependencyProperty.Register("SelectedTimeFormat", typeof(string), typeof(TimePicker), + new PropertyMetadata("HH:mm:ss")); + + public static readonly DependencyProperty MaxDropDownHeightProperty = + DependencyProperty.Register("MaxDropDownHeight", typeof(double), typeof(TimePicker), + new UIPropertyMetadata(SystemParameters.PrimaryScreenHeight / 3.0, OnMaxDropDownHeightChanged)); + + public static readonly DependencyProperty SelectedTimeProperty = + DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePicker), + new PropertyMetadata(null, OnSelectedTimeChanged)); + + public static readonly DependencyProperty IsCurrentTimeProperty = + DependencyProperty.Register("IsCurrentTime", typeof(bool), typeof(TimePicker), new PropertyMetadata(false)); + + private DateTime _date; + private Popup _popup; + private TextBox _textBox; + private TimeSelector _timeSelector; + + static TimePicker() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePicker), + new FrameworkPropertyMetadata(typeof(TimePicker))); + } + + public string SelectedTimeFormat + { + get => (string) GetValue(SelectedTimeFormatProperty); + set => SetValue(SelectedTimeFormatProperty, value); + } + + public DateTime? SelectedTime + { + get => (DateTime?) GetValue(SelectedTimeProperty); + set => SetValue(SelectedTimeProperty, value); + } + + public bool IsCurrentTime + { + get => (bool) GetValue(IsCurrentTimeProperty); + set => SetValue(IsCurrentTimeProperty, value); + } + + private static void OnMaxDropDownHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctrl = d as TimePicker; + if (ctrl != null) + ctrl.OnMaxDropDownHeightChanged((double) e.OldValue, (double) e.NewValue); + } + + protected virtual void OnMaxDropDownHeightChanged(double oldValue, double newValue) + { + } + + private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctrl = d as TimePicker; + if (ctrl != null && e.NewValue != null) + { + var dateTime = (DateTime) e.NewValue; + if (ctrl._timeSelector != null && dateTime > DateTime.MinValue) + ctrl._timeSelector.SelectedTime = dateTime; + else + ctrl._date = dateTime; + } + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + _textBox = GetTemplateChild(EditableTextBoxTemplateName) as TextBox; + _timeSelector = GetTemplateChild(TimeSelectorTemplateName) as TimeSelector; + if (_timeSelector != null) + { + _timeSelector.SelectedTimeChanged -= TimeSelector_SelectedTimeChanged; + _timeSelector.SelectedTimeChanged += TimeSelector_SelectedTimeChanged; + if (!SelectedTime.HasValue && IsCurrentTime) + { + SelectedTime = DateTime.Now; + } + else + { + SelectedTime = null; + SelectedTime = _date; + } + } + + _popup = GetTemplateChild(PopupTemplateName) as Popup; + if (_popup != null) + { + _popup.Opened -= Popup_Opened; + _popup.Opened += Popup_Opened; + } + } + + private void Popup_Opened(object sender, EventArgs e) + { + if (_timeSelector != null) + _timeSelector.SetTime(); + } + + private void TimeSelector_SelectedTimeChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (_textBox != null && e.NewValue != null) + { + _textBox.Text = e.NewValue.Value.ToString(SelectedTimeFormat); + SelectedTime = e.NewValue; + } + } + } +} \ No newline at end of file From 2b42bc7d45f81e244ddb265d7edf131928d29ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:38:29 +0800 Subject: [PATCH 06/20] add FindVisualChild --- .../Core/Helpers/ControlsHelper.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/WPFDevelopers.Shared/Core/Helpers/ControlsHelper.cs b/src/WPFDevelopers.Shared/Core/Helpers/ControlsHelper.cs index 81cc7d96..23f83e51 100644 --- a/src/WPFDevelopers.Shared/Core/Helpers/ControlsHelper.cs +++ b/src/WPFDevelopers.Shared/Core/Helpers/ControlsHelper.cs @@ -12,8 +12,6 @@ using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; -using WPFDevelopers.Controls; -using WPFDevelopers.Utilities; namespace WPFDevelopers.Helpers { @@ -254,6 +252,21 @@ public static Thickness GetPadding(FrameworkElement element) return new Thickness(); } + public static T FindVisualChild(DependencyObject parent) where T : DependencyObject + { + int childCount = VisualTreeHelper.GetChildrenCount(parent); + for (int i = 0; i < childCount; i++) + { + var child = VisualTreeHelper.GetChild(parent, i); + if (child is T typedChild) + return typedChild; + var result = FindVisualChild(child); + if (result != null) + return result; + } + return null; + } + } From 8626729c1baed95a8e7d6cb38504b5b937adc523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:38:49 +0800 Subject: [PATCH 07/20] Update PackIconKind.cs --- src/WPFDevelopers.Shared/Controls/PathIcon/PackIconKind.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WPFDevelopers.Shared/Controls/PathIcon/PackIconKind.cs b/src/WPFDevelopers.Shared/Controls/PathIcon/PackIconKind.cs index 3d8f7708..55c20085 100644 --- a/src/WPFDevelopers.Shared/Controls/PathIcon/PackIconKind.cs +++ b/src/WPFDevelopers.Shared/Controls/PathIcon/PackIconKind.cs @@ -52,5 +52,6 @@ public enum PackIconKind [Description("WD.HomeGeometry")] Home, [Description("WD.BreadCrumbBarGeometry")] BreadCrumbBar, [Description("WD.UnfoldMoreGeometry")] UnfoldMore, + [Description("WD.TimeGeometry")] Time, } } From c8de3c72611904764bf1b269dbcc6881286cc566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E9=A9=9A=E9=8F=B5?= Date: Sun, 17 Sep 2023 23:39:12 +0800 Subject: [PATCH 08/20] Create TimePicker.xaml --- .../Themes/TimePicker.xaml | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 src/WPFDevelopers.Shared/Themes/TimePicker.xaml diff --git a/src/WPFDevelopers.Shared/Themes/TimePicker.xaml b/src/WPFDevelopers.Shared/Themes/TimePicker.xaml new file mode 100644 index 00000000..2faacbad --- /dev/null +++ b/src/WPFDevelopers.Shared/Themes/TimePicker.xaml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +