From 7585d86fb540a2b074c6c81198825ab661eb9afe Mon Sep 17 00:00:00 2001 From: Mahdi Hosseini Date: Sat, 11 May 2019 19:17:10 +0430 Subject: [PATCH 1/2] add TimePickerList --- .../Controls/TimePickerDemoCtl.xaml | 2 + .../Controls/Time/ItemsControlExtensions.cs | 79 ++++ .../Controls/Time/TimeButton.cs | 42 ++ .../Controls/Time/TimePickerList.cs | 114 ++++++ .../Controls/Time/TimeSelector.cs | 380 ++++++++++++++++++ .../HandyControl_Shared.projitems | 12 + .../Themes/Styles/Style.xaml | 2 + .../Themes/Styles/TimePickerList.xaml | 88 ++++ .../Themes/Styles/TimeSelector.xaml | 89 ++++ 9 files changed, 808 insertions(+) create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs create mode 100644 src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml create mode 100644 src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml index 840acbb5..63143963 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml @@ -7,6 +7,8 @@ + + diff --git a/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs b/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs new file mode 100644 index 00000000..8cea4c60 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Media.Animation; + +namespace HandyControl.Controls +{ + /// + /// ItemsControl扩展方法 + /// + public static class ItemsControlExtensions + { + /// + /// 平滑滚动至指定元素 + /// + /// + /// + public static void AnimateScrollIntoView(this ItemsControl itemsControl, object item) + { + ScrollViewer scrollViewer = FindVisualChild(itemsControl); + if (scrollViewer == null) + { + return; + } + + UIElement container = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as UIElement; + + if (container == null) + { + return; + } + + int index = itemsControl.ItemContainerGenerator.IndexFromContainer(container); + + //平滑滚动到元素所在位置 + //double toValue = scrollViewer.ScrollableHeight * ((double)index / itemsControl.Items.Count); + //平滑滚动,将选中的元素置顶 + double toValue = VisualTreeHelper.GetOffset(container).Y; + + DoubleAnimation verticalAnimation = new DoubleAnimation(); + verticalAnimation.From = scrollViewer.VerticalOffset; + verticalAnimation.To = toValue; + verticalAnimation.DecelerationRatio = .2; + verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(200)); + Storyboard storyboard = new Storyboard(); + storyboard.Children.Add(verticalAnimation); + Storyboard.SetTarget(verticalAnimation, scrollViewer); + Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(ScrollViewerBehavior.VerticalOffsetProperty)); + storyboard.Begin(); + } + + /// + /// 查找元素的子元素 + /// + /// 子元素类型 + /// + /// + public static T FindVisualChild(DependencyObject obj) where T : DependencyObject + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) + { + DependencyObject child = VisualTreeHelper.GetChild(obj, i); + if (child != null && child is T) + return (T)child; + else + { + T childOfChild = FindVisualChild(child); + if (childOfChild != null) + return childOfChild; + } + } + return null; + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs new file mode 100644 index 00000000..751bb887 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace HandyControl.Controls +{ + public class TimeButton : ListBoxItem + { + #region Private属性 + #endregion + + #region 依赖属性定义 + + #endregion + + #region 依赖属性set get + + #endregion + + #region Constructors + static TimeButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TimeButton), new FrameworkPropertyMetadata(typeof(TimeButton))); + } + #endregion + + #region Override方法 + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + } + #endregion + + #region Private方法 + + #endregion + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs new file mode 100644 index 00000000..9605dfc0 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; + +namespace HandyControl.Controls +{ + public class TimePickerList : Control + { + #region Private属性 + private TextBox PART_TextBox; + private TimeSelector PART_TimeSelector; + private Popup PART_Popup; + #endregion + + #region 依赖属性定义 + + #endregion + + #region 依赖属性set get + + #region TimeStringFormat + public string TimeStringFormat + { + get { return (string)GetValue(TimeStringFormatProperty); } + set { SetValue(TimeStringFormatProperty, value); } + } + + public static readonly DependencyProperty TimeStringFormatProperty = + DependencyProperty.Register("TimeStringFormat", typeof(string), typeof(TimePickerList), new PropertyMetadata("HH:mm:ss")); + #endregion + + #region SelectedTime + public DateTime? SelectedTime + { + get { return (DateTime?)GetValue(SelectedTimeProperty); } + set { SetValue(SelectedTimeProperty, value); } + } + + public static readonly DependencyProperty SelectedTimeProperty = + DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePickerList), new PropertyMetadata(null, SelectedTimeChangedCallback)); + + private static void SelectedTimeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TimePickerList timePicker = d as TimePickerList; + DateTime dt = (DateTime)e.NewValue; + + timePicker.PART_TimeSelector.SelectedTime = dt; + } + #endregion + + #region DropDownHeight + + public double DropDownHeight + { + get { return (double)GetValue(DropDownHeightProperty); } + set { SetValue(DropDownHeightProperty, value); } + } + + public static readonly DependencyProperty DropDownHeightProperty = + DependencyProperty.Register("DropDownHeight", typeof(double), typeof(TimePickerList), new PropertyMetadata(168d)); + + #endregion + + #endregion + + #region Constructors + static TimePickerList() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePickerList), new FrameworkPropertyMetadata(typeof(TimePickerList))); + } + #endregion + + #region Override方法 + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + this.PART_TextBox = this.GetTemplateChild("PART_TextBox") as TextBox; + this.PART_TimeSelector = this.GetTemplateChild("PART_TimeSelector") as TimeSelector; + this.PART_Popup = this.GetTemplateChild("PART_Popup") as Popup; + if (this.PART_TimeSelector != null) + { + this.PART_TimeSelector.Owner = this; + this.PART_TimeSelector.SelectedTimeChanged += PART_TimeSelector_SelectedTimeChanged; + } + if (this.PART_Popup != null) + { + this.PART_Popup.Opened += PART_Popup_Opened; + } + } + + private void PART_Popup_Opened(object sender, EventArgs e) + { + this.PART_TimeSelector.SetButtonSelected(); + } + #endregion + + #region Private方法 + private void PART_TimeSelector_SelectedTimeChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (this.PART_TextBox != null && e.NewValue != null) + { + this.PART_TextBox.Text = e.NewValue.Value.ToString(this.TimeStringFormat); + this.SelectedTime = e.NewValue; + } + } + #endregion + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs new file mode 100644 index 00000000..e2eb030a --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Media.Animation; + +namespace HandyControl.Controls +{ + public class TimeSelector : Control + { + private ObservableCollection HourButtons = new ObservableCollection(); + private ObservableCollection MinuteButtons = new ObservableCollection(); + private ObservableCollection SecondButtons = new ObservableCollection(); + + #region 控件内部元素 + private ListBox PART_Hour; + private ListBox PART_Minute; + private ListBox PART_Second; + #endregion + + #region 私有属性 + private int Hour = 0; + private int Minute = 0; + private int Second = 0; + #endregion + + #region Fields + public TimePickerList Owner { get; set; } + #endregion + + #region 事件定义 + + #region SelectedTimeChanged + public static readonly RoutedEvent SelectedTimeChangedEvent = EventManager.RegisterRoutedEvent("SelectedTimeChanged", + RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(TimeSelector)); + + public event RoutedPropertyChangedEventHandler SelectedTimeChanged + { + add + { + this.AddHandler(SelectedTimeChangedEvent, value); + } + remove + { + this.RemoveHandler(SelectedTimeChangedEvent, value); + } + } + + public virtual void OnSelectedTimeChanged(DateTime? oldValue, DateTime? newValue) + { + RoutedPropertyChangedEventArgs arg = new RoutedPropertyChangedEventArgs(oldValue, newValue, SelectedTimeChangedEvent); + this.RaiseEvent(arg); + } + #endregion + + #endregion + + #region 依赖属性set get + + #region SelectedTime + public DateTime? SelectedTime + { + get { return (DateTime?)GetValue(SelectedTimeProperty); } + set { SetValue(SelectedTimeProperty, value); } + } + + public static readonly DependencyProperty SelectedTimeProperty = + DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimeSelector), new PropertyMetadata(null, SelectedTimeChangedCallback)); + + private static void SelectedTimeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TimeSelector timeSelector = d as TimeSelector; + DateTime dt = (DateTime)e.NewValue; + + timeSelector.SetButtonSelected(); + + timeSelector.OnSelectedTimeChanged((DateTime?)e.OldValue, (DateTime?)e.NewValue); + } + + public void SetButtonSelected() + { + if (!this.SelectedTime.HasValue) + { + return; + } + + this.Hour = this.SelectedTime.Value.Hour; + this.Minute = this.SelectedTime.Value.Minute; + this.Second = this.SelectedTime.Value.Second; + + if (this.PART_Hour != null) + { + for (int i = 0; i < this.PART_Hour.Items.Count; i++) + { + TimeButton timeButton = this.PART_Hour.Items[i] as TimeButton; + if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Hour))) + { + this.PART_Hour.SelectedIndex = i; + this.PART_Hour.AnimateScrollIntoView(timeButton); + break; + } + } + } + + if (this.PART_Minute != null) + { + for (int i = 0; i < this.PART_Minute.Items.Count; i++) + { + TimeButton timeButton = this.PART_Minute.Items[i] as TimeButton; + if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Minute))) + { + this.PART_Minute.SelectedIndex = i; + this.PART_Minute.AnimateScrollIntoView(timeButton); + break; + } + } + } + + if (this.PART_Second != null) + { + for (int i = 0; i < this.PART_Second.Items.Count; i++) + { + TimeButton timeButton = this.PART_Second.Items[i] as TimeButton; + if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Second))) + { + this.PART_Second.SelectedIndex = i; + this.PART_Second.AnimateScrollIntoView(timeButton); + break; + } + } + } + } + #endregion + + #region SelectedHour + public int? SelectedHour + { + get { return (int?)GetValue(SelectedHourProperty); } + set { SetValue(SelectedHourProperty, value); } + } + + public static readonly DependencyProperty SelectedHourProperty = + DependencyProperty.Register("SelectedHour", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedHourChanged)); + + private static void SelectedHourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TimeSelector timeSelector = d as TimeSelector; + timeSelector.Hour = e.NewValue == null ? 0 : (int)e.NewValue; + timeSelector.SetSelectedTime(); + } + #endregion + + #region SelectedMinute + + public int? SelectedMinute + { + get { return (int?)GetValue(SelectedMinuteProperty); } + set { SetValue(SelectedMinuteProperty, value); } + } + + public static readonly DependencyProperty SelectedMinuteProperty = + DependencyProperty.Register("SelectedMinute", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedMinuteChanged)); + + private static void SelectedMinuteChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TimeSelector timeSelector = d as TimeSelector; + + timeSelector.Minute = e.NewValue == null ? 0 : (int)e.NewValue; + timeSelector.SetSelectedTime(); + } + + #endregion + + #region SelectedSecond + + public int? SelectedSecond + { + get { return (int?)GetValue(SelectedSecondProperty); } + set { SetValue(SelectedSecondProperty, value); } + } + + public static readonly DependencyProperty SelectedSecondProperty = + DependencyProperty.Register("SelectedSecond", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedSecondChanged)); + + private static void SelectedSecondChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TimeSelector timeSelector = d as TimeSelector; + + timeSelector.Second = e.NewValue == null ? 0 : (int)e.NewValue; + timeSelector.SetSelectedTime(); + } + + #endregion + + #region ItemHeight + public double ItemHeight + { + get { return (double)GetValue(ItemHeightProperty); } + set { SetValue(ItemHeightProperty, value); } + } + + public static readonly DependencyProperty ItemHeightProperty = + DependencyProperty.Register("ItemHeight", typeof(double), typeof(TimeSelector), new PropertyMetadata(28.0)); + #endregion + + #endregion + + #region Constructors + static TimeSelector() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TimeSelector), new FrameworkPropertyMetadata(typeof(TimeSelector))); + } + #endregion + + #region Override方法 + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + this.PART_Hour = this.GetTemplateChild("PART_Hour") as ListBox; + this.PART_Minute = this.GetTemplateChild("PART_Minute") as ListBox; + this.PART_Second = this.GetTemplateChild("PART_Second") as ListBox; + + if (this.PART_Hour != null) + { + this.CreateHourButtons(); + this.PART_Hour.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(HourButton_Click), true); + } + + if (this.PART_Minute != null) + { + this.CreateMinuteButtons(); + this.PART_Minute.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(MinuteButton_Click), true); + } + + if (this.PART_Second != null) + { + this.CreateSecondButtons(); + this.PART_Second.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(SecondButton_Click), true); + } + } + #endregion + + #region Private方法 + + private void MinuteButton_Click(object sender, RoutedEventArgs e) + { + TimeButton selectedItem = this.PART_Minute.SelectedItem as TimeButton; + if (selectedItem == null) + { + return; + } + this.SelectedMinute = Convert.ToInt32(selectedItem.DataContext); + this.PART_Minute.AnimateScrollIntoView(selectedItem); + } + + private void SecondButton_Click(object sender, RoutedEventArgs e) + { + TimeButton selectedItem = this.PART_Second.SelectedItem as TimeButton; + if (selectedItem == null) + { + return; + } + this.SelectedSecond = Convert.ToInt32(selectedItem.DataContext); + this.PART_Second.AnimateScrollIntoView(selectedItem); + } + + private void HourButton_Click(object sender, RoutedEventArgs e) + { + TimeButton selectedItem = this.PART_Hour.SelectedItem as TimeButton; + if (selectedItem == null) + { + return; + } + this.SelectedHour = Convert.ToInt32(selectedItem.DataContext); + this.PART_Hour.AnimateScrollIntoView(selectedItem); + } + + private void CreateHourButtons() + { + this.CreateItems(24, this.HourButtons); + this.CreateExtraItem(this.HourButtons); + this.PART_Hour.ItemsSource = this.HourButtons; + } + + private void CreateMinuteButtons() + { + this.CreateItems(60, this.MinuteButtons); + this.CreateExtraItem(this.MinuteButtons); + this.PART_Minute.ItemsSource = this.MinuteButtons; + } + + private void CreateSecondButtons() + { + this.CreateItems(60, this.SecondButtons); + this.CreateExtraItem(this.SecondButtons); + this.PART_Second.ItemsSource = this.SecondButtons; + } + + private void CreateItems(int itemsCount, ObservableCollection list) + { + for (int i = 0; i < itemsCount; i++) + { + TimeButton timeButton = new TimeButton(); + timeButton.SetValue(TimeButton.HeightProperty, this.ItemHeight); + timeButton.SetValue(TimeButton.DataContextProperty, i); + timeButton.SetValue(TimeButton.ContentProperty, (i < 10) ? "0" + i : i.ToString()); + timeButton.SetValue(TimeButton.IsSelectedProperty, false); + list.Add(timeButton); + } + } + + private void CreateExtraItem(ObservableCollection list) + { + double height = this.ItemHeight; + if (this.Owner != null) + { + height = this.Owner.DropDownHeight; + } + else + { + height = double.IsNaN(this.Height) ? height : this.Height; + } + + for (int i = 0; i < (height - this.ItemHeight) / this.ItemHeight; i++) + { + TimeButton timeButton = new TimeButton(); + timeButton.SetValue(TimeButton.HeightProperty, this.ItemHeight); + timeButton.SetValue(TimeButton.IsEnabledProperty, false); + timeButton.SetValue(TimeButton.IsSelectedProperty, false); + list.Add(timeButton); + } + } + + private DateTime GetDateTime(int hour, int minute, int second) + { + DateTime dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, hour, minute, second); + return dt; + } + + /// + /// 设置选中的时间 + /// + private void SetSelectedTime() + { + DateTime dt = this.GetDateTime(this.Hour, this.Minute, this.Second); + this.SelectedTime = dt; + } + #endregion + } + public class ScrollViewerBehavior + { + public static DependencyProperty VerticalOffsetProperty = + DependencyProperty.RegisterAttached("VerticalOffset", + typeof(double), + typeof(ScrollViewerBehavior), + new UIPropertyMetadata(0.0, OnVerticalOffsetChanged)); + + public static void SetVerticalOffset(FrameworkElement target, double value) + { + target.SetValue(VerticalOffsetProperty, value); + } + public static double GetVerticalOffset(FrameworkElement target) + { + return (double)target.GetValue(VerticalOffsetProperty); + } + private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) + { + ScrollViewer scrollViewer = target as ScrollViewer; + if (scrollViewer != null) + { + scrollViewer.ScrollToVerticalOffset((double)e.NewValue); + } + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 7006f532..801e85b4 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -98,8 +98,12 @@ + + + + @@ -698,6 +702,14 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml index 5a971e9d..56d1f56c 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml @@ -63,6 +63,8 @@ + + \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml new file mode 100644 index 00000000..ff291905 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml new file mode 100644 index 00000000..3dd43aaa --- /dev/null +++ b/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml @@ -0,0 +1,89 @@ + + + + + + + + + \ No newline at end of file From 583c6413023e91c606ab8fdfb2479326ad6a07d4 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sun, 12 May 2019 20:20:04 +0800 Subject: [PATCH 2/2] modified the pr --- .../Controls/TimePickerDemoCtl.xaml | 8 +- .../Controls/Input/DateTimePicker.cs | 9 - .../Controls/Input/TimePicker.cs | 76 ++-- .../Controls/Other/ScrollViewer.cs | 8 +- .../Controls/Time/Clock/Clock.cs | 129 +----- .../Controls/Time/Clock/ClockBase.cs | 106 +++++ .../Controls/Time/Clock/ListClock.cs | 148 +++++++ .../Controls/Time/ItemsControlExtensions.cs | 79 ---- .../Controls/Time/TimeButton.cs | 42 -- .../Controls/Time/TimePickerList.cs | 114 ------ .../Controls/Time/TimeSelector.cs | 380 ------------------ .../Data/Gif/GifImageInfo.cs | 1 + .../HandyControl_Shared.projitems | 14 +- .../Themes/Styles/Clock.xaml | 73 +++- .../Themes/Styles/Style.xaml | 2 - .../Themes/Styles/TimePickerList.xaml | 88 ---- .../Themes/Styles/TimeSelector.xaml | 89 ---- .../Tools/GifImageAnimator.cs | 3 +- 18 files changed, 395 insertions(+), 974 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/Clock/ClockBase.cs create mode 100644 src/Shared/HandyControl_Shared/Controls/Time/Clock/ListClock.cs delete mode 100644 src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs delete mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs delete mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs delete mode 100644 src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs delete mode 100644 src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml delete mode 100644 src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml index 63143963..0c4355c8 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml @@ -7,8 +7,6 @@ - - @@ -19,7 +17,11 @@ - + + + + + diff --git a/src/Shared/HandyControl_Shared/Controls/Input/DateTimePicker.cs b/src/Shared/HandyControl_Shared/Controls/Input/DateTimePicker.cs index c32c83ec..c76112b6 100644 --- a/src/Shared/HandyControl_Shared/Controls/Input/DateTimePicker.cs +++ b/src/Shared/HandyControl_Shared/Controls/Input/DateTimePicker.cs @@ -99,15 +99,6 @@ namespace HandyControl.Controls set => SetValue(DateTimeFormatProperty, value); } - public static readonly DependencyProperty ClockStyleProperty = DependencyProperty.Register( - "ClockStyle", typeof(Style), typeof(DateTimePicker), new PropertyMetadata(default(Style))); - - public Style ClockStyle - { - get => (Style) GetValue(ClockStyleProperty); - set => SetValue(ClockStyleProperty, value); - } - public static readonly DependencyProperty CalendarStyleProperty = DependencyProperty.Register( "CalendarStyle", typeof(Style), typeof(DateTimePicker), new PropertyMetadata(default(Style))); diff --git a/src/Shared/HandyControl_Shared/Controls/Input/TimePicker.cs b/src/Shared/HandyControl_Shared/Controls/Input/TimePicker.cs index 25d005de..021d7f7a 100644 --- a/src/Shared/HandyControl_Shared/Controls/Input/TimePicker.cs +++ b/src/Shared/HandyControl_Shared/Controls/Input/TimePicker.cs @@ -34,8 +34,6 @@ namespace HandyControl.Controls #region Data - private Clock _clock; - private string _defaultText; private ButtonBase _dropDownButton; @@ -79,7 +77,7 @@ namespace HandyControl.Controls public TimePicker() { - InitClock(); + Clock = new Clock(); CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) => { ClearValue(SelectedTimeProperty); @@ -103,18 +101,6 @@ namespace HandyControl.Controls #endregion TimeFormat - #region ClockStyle - - public Style ClockStyle - { - get => (Style)GetValue(ClockStyleProperty); - set => SetValue(ClockStyleProperty, value); - } - - public static readonly DependencyProperty ClockStyleProperty = DependencyProperty.Register("ClockStyle", typeof(Style), typeof(TimePicker)); - - #endregion CalendarStyle - #region DisplayTime public DateTime DisplayTime @@ -133,8 +119,8 @@ namespace HandyControl.Controls private static object CoerceDisplayTime(DependencyObject d, object value) { var dp = (TimePicker)d; - dp._clock.DisplayTime = (DateTime)value; - return dp._clock.DisplayTime; + dp.Clock.DisplayTime = (DateTime)value; + return dp.Clock.DisplayTime; } #endregion DisplayTime @@ -170,7 +156,7 @@ namespace HandyControl.Controls dp.Dispatcher.BeginInvoke(DispatcherPriority.Input, (Action)delegate { - dp._clock.Focus(); + dp.Clock.Focus(); }); } } @@ -212,8 +198,8 @@ namespace HandyControl.Controls private static object CoerceSelectedTime(DependencyObject d, object value) { var dp = (TimePicker)d; - dp._clock.SelectedTime = (DateTime?)value; - return dp._clock.SelectedTime; + dp.Clock.SelectedTime = (DateTime?)value; + return dp.Clock.SelectedTime; } #endregion SelectedDate @@ -306,6 +292,35 @@ namespace HandyControl.Controls set => SetValue(ShowClearButtonProperty, value); } + public static readonly DependencyProperty ClockProperty = DependencyProperty.Register( + "Clock", typeof(ClockBase), typeof(TimePicker), new FrameworkPropertyMetadata(default(Clock), FrameworkPropertyMetadataOptions.NotDataBindable, OnClockChanged)); + + private static void OnClockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (TimePicker) d; + var oldClock = e.OldValue as ClockBase; + var newClock = e.NewValue as ClockBase; + + if (oldClock != null) + { + oldClock.SelectedTimeChanged -= ctl.Clock_SelectedTimeChanged; + oldClock.Confirmed -= ctl.Clock_Confirmed; + } + + if (newClock != null) + { + newClock.ShowConfirmButton = true; + newClock.SelectedTimeChanged += ctl.Clock_SelectedTimeChanged; + newClock.Confirmed += ctl.Clock_Confirmed; + } + } + + public ClockBase Clock + { + get => (ClockBase) GetValue(ClockProperty); + set => SetValue(ClockProperty, value); + } + #endregion Public Properties #region Public Methods @@ -374,7 +389,7 @@ namespace HandyControl.Controls _popUp.PreviewMouseLeftButtonDown += PopUp_PreviewMouseLeftButtonDown; _popUp.Opened += PopUp_Opened; _popUp.Closed += PopUp_Closed; - _popUp.Child = _clock; + _popUp.Child = Clock; if (IsDropDownOpen) { @@ -439,20 +454,7 @@ namespace HandyControl.Controls throw new Exception(); } - private void InitClock() - { - _clock = new Clock - { - ShowConfirmButton = true - }; - _clock.SelectedTimeChanged += Clock_SelectedTimeChanged; - _clock.Confirmed += Clock_Confirmed; - } - - private void TextBox_LostFocus(object sender, RoutedEventArgs e) - { - SetSelectedTime(); - } + private void TextBox_LostFocus(object sender, RoutedEventArgs e) => SetSelectedTime(); private void SetIsHandlerSuspended(DependencyProperty property, bool value) { @@ -560,7 +562,7 @@ namespace HandyControl.Controls SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.TrueBox); } - _clock?.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + Clock?.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); OnClockOpened(new RoutedEventArgs()); } @@ -572,7 +574,7 @@ namespace HandyControl.Controls SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.FalseBox); } - if (_clock.IsKeyboardFocusWithin) + if (Clock.IsKeyboardFocusWithin) { MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); } diff --git a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs index a6734670..764f4c3e 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs @@ -192,7 +192,7 @@ namespace HandyControl.Controls /// /// 当前垂直滚动偏移 /// - private static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register( + internal static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register( "CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged)); private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -206,7 +206,7 @@ namespace HandyControl.Controls /// /// 当前垂直滚动偏移 /// - private double CurrentVerticalOffset + internal double CurrentVerticalOffset { // ReSharper disable once UnusedMember.Local get => (double) GetValue(CurrentVerticalOffsetProperty); @@ -216,7 +216,7 @@ namespace HandyControl.Controls /// /// 当前水平滚动偏移 /// - public static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register( + internal static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register( "CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged)); private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -230,7 +230,7 @@ namespace HandyControl.Controls /// /// 当前水平滚动偏移 /// - public double CurrentHorizontalOffset + internal double CurrentHorizontalOffset { get => (double) GetValue(CurrentHorizontalOffsetProperty); set => SetValue(CurrentHorizontalOffsetProperty, value); diff --git a/src/Shared/HandyControl_Shared/Controls/Time/Clock/Clock.cs b/src/Shared/HandyControl_Shared/Controls/Time/Clock/Clock.cs index ca43b8da..7c0dead1 100644 --- a/src/Shared/HandyControl_Shared/Controls/Time/Clock/Clock.cs +++ b/src/Shared/HandyControl_Shared/Controls/Time/Clock/Clock.cs @@ -6,26 +6,23 @@ using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; -using HandyControl.Data; using HandyControl.Tools; namespace HandyControl.Controls { [TemplatePart(Name = ElementButtonAm, Type = typeof(RadioButton))] [TemplatePart(Name = ElementButtonPm, Type = typeof(RadioButton))] - [TemplatePart(Name = ElementButtonConfirm, Type = typeof(Button))] [TemplatePart(Name = ElementCanvas, Type = typeof(Canvas))] [TemplatePart(Name = ElementBorderTitle, Type = typeof(Border))] [TemplatePart(Name = ElementBorderClock, Type = typeof(Border))] [TemplatePart(Name = ElementPanelNum, Type = typeof(CirclePanel))] [TemplatePart(Name = ElementTimeStr, Type = typeof(TextBlock))] - public class Clock : Control + public class Clock : ClockBase { #region Constants private const string ElementButtonAm = "PART_ButtonAm"; private const string ElementButtonPm = "PART_ButtonPm"; - private const string ElementButtonConfirm = "PART_ButtonConfirm"; private const string ElementCanvas = "PART_Canvas"; private const string ElementBorderTitle = "PART_BorderTitle"; private const string ElementBorderClock = "PART_BorderClock"; @@ -40,8 +37,6 @@ namespace HandyControl.Controls private RadioButton _buttonPm; - private Button _buttonConfirm; - private Canvas _canvas; private Border _borderTitle; @@ -60,59 +55,10 @@ namespace HandyControl.Controls private int _secValue; - private bool _appliedTemplate; - #endregion Data - #region Public Events - - public static readonly RoutedEvent SelectedTimeChangedEvent = - EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Direct, - typeof(EventHandler>), typeof(Clock)); - - public event EventHandler> SelectedTimeChanged - { - add => AddHandler(SelectedTimeChangedEvent, value); - remove => RemoveHandler(SelectedTimeChangedEvent, value); - } - - public event EventHandler> DisplayTimeChanged; - - public event Action Confirmed; - - #endregion Public Events - #region Public Properties - public static readonly DependencyProperty SelectedTimeProperty = DependencyProperty.Register( - "SelectedTime", typeof(DateTime?), typeof(Clock), new PropertyMetadata(default(DateTime?), OnSelectedTimeChanged)); - - private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var ctl = (Clock)d; - var v = (DateTime?)e.NewValue; - ctl.DisplayTime = v ?? DateTime.Now; - ctl.OnSelectedTimeChanged(new FunctionEventArgs(SelectedTimeChangedEvent, ctl) - { - Info = v - }); - } - - public DateTime? SelectedTime - { - get => (DateTime?) GetValue(SelectedTimeProperty); - set => SetValue(SelectedTimeProperty, value); - } - - public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register( - "TimeFormat", typeof(string), typeof(Clock), new PropertyMetadata("HH:mm:ss")); - - public string TimeFormat - { - get => (string) GetValue(TimeFormatProperty); - set => SetValue(TimeFormatProperty, value); - } - public static readonly DependencyProperty ClockRadioButtonStyleProperty = DependencyProperty.Register( "ClockRadioButtonStyle", typeof(Style), typeof(Clock), new PropertyMetadata(default(Style))); @@ -122,32 +68,6 @@ namespace HandyControl.Controls set => SetValue(ClockRadioButtonStyleProperty, value); } - public static readonly DependencyProperty DisplayTimeProperty = DependencyProperty.Register( - "DisplayTime", typeof(DateTime), typeof(Clock), new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDisplayTimeChanged)); - - private static void OnDisplayTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var ctl = (Clock) d; - var v = (DateTime) e.NewValue; - ctl.Update(v); - ctl.OnDisplayTimeChanged(new FunctionEventArgs(v)); - } - - public DateTime DisplayTime - { - get => (DateTime) GetValue(DisplayTimeProperty); - set => SetValue(DisplayTimeProperty, value); - } - - internal static readonly DependencyProperty ShowConfirmButtonProperty = DependencyProperty.Register( - "ShowConfirmButton", typeof(bool), typeof(Clock), new PropertyMetadata(ValueBoxes.FalseBox)); - - internal bool ShowConfirmButton - { - get => (bool)GetValue(ShowConfirmButtonProperty); - set => SetValue(ShowConfirmButtonProperty, value); - } - private int SecValue { get => _secValue; @@ -174,7 +94,7 @@ namespace HandyControl.Controls public override void OnApplyTemplate() { - _appliedTemplate = false; + AppliedTemplate = false; if (_buttonAm != null) { _buttonAm.Click -= ButtonAm_OnClick; @@ -185,9 +105,9 @@ namespace HandyControl.Controls _buttonPm.Click -= ButtonPm_OnClick; } - if (_buttonConfirm != null) + if (ButtonConfirm != null) { - _buttonConfirm.Click -= ButtonConfirm_OnClick; + ButtonConfirm.Click -= ButtonConfirm_OnClick; } if (_borderTitle != null) @@ -206,18 +126,18 @@ namespace HandyControl.Controls _buttonAm = GetTemplateChild(ElementButtonAm) as RadioButton; _buttonPm = GetTemplateChild(ElementButtonPm) as RadioButton; - _buttonConfirm = GetTemplateChild(ElementButtonConfirm) as Button; + ButtonConfirm = GetTemplateChild(ElementButtonConfirm) as Button; _borderTitle = GetTemplateChild(ElementBorderTitle) as Border; _canvas = GetTemplateChild(ElementCanvas) as Canvas; _borderClock = GetTemplateChild(ElementBorderClock) as Border; _circlePanel = GetTemplateChild(ElementPanelNum) as CirclePanel; _blockTime = GetTemplateChild(ElementTimeStr) as TextBlock; - CheckNull(); + if (!CheckNull()) return; _buttonAm.Click += ButtonAm_OnClick; _buttonPm.Click += ButtonPm_OnClick; - _buttonConfirm.Click += ButtonConfirm_OnClick; + ButtonConfirm.Click += ButtonConfirm_OnClick; _borderTitle.MouseWheel += BorderTitle_OnMouseWheel; _canvas.MouseWheel += Canvas_OnMouseWheel; @@ -241,7 +161,7 @@ namespace HandyControl.Controls _circlePanel.Children.Add(button); } - _appliedTemplate = true; + AppliedTemplate = true; if (SelectedTime.HasValue) { Update(SelectedTime.Value); @@ -255,26 +175,15 @@ namespace HandyControl.Controls #endregion Public Methods - #region Protected Methods - - protected virtual void OnSelectedTimeChanged(FunctionEventArgs e) => RaiseEvent(e); - - protected virtual void OnDisplayTimeChanged(FunctionEventArgs e) - { - var handler = DisplayTimeChanged; - handler?.Invoke(this, e); - } - - #endregion Protected Methods - #region Private Methods - private void CheckNull() + private bool CheckNull() { - - if (_buttonPm == null || _buttonAm == null || _buttonConfirm == null || _canvas == null || + if (_buttonPm == null || _buttonAm == null || ButtonConfirm == null || _canvas == null || _borderTitle == null || _borderClock == null || _circlePanel == null || - _blockTime == null) throw new Exception(); + _blockTime == null) return false; + + return true; } private void BorderTitle_OnMouseWheel(object sender, MouseWheelEventArgs e) @@ -339,7 +248,7 @@ namespace HandyControl.Controls private void Update() { - if (!_appliedTemplate) return; + if (!AppliedTemplate) return; var hValue = _currentButton.Num; if (_buttonPm.IsChecked == true) { @@ -367,9 +276,9 @@ namespace HandyControl.Controls /// 更新 /// /// - internal void Update(DateTime time) + internal override void Update(DateTime time) { - if (!_appliedTemplate) return; + if (!AppliedTemplate) return; var h = time.Hour; var m = time.Minute; @@ -396,12 +305,6 @@ namespace HandyControl.Controls Update(); } - private void ButtonConfirm_OnClick(object sender, RoutedEventArgs e) - { - SelectedTime = DisplayTime; - Confirmed?.Invoke(); - } - /// /// 获取显示时间 /// diff --git a/src/Shared/HandyControl_Shared/Controls/Time/Clock/ClockBase.cs b/src/Shared/HandyControl_Shared/Controls/Time/Clock/ClockBase.cs new file mode 100644 index 00000000..c2ef4420 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/Clock/ClockBase.cs @@ -0,0 +1,106 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using HandyControl.Data; + +namespace HandyControl.Controls +{ + [TemplatePart(Name = ElementButtonConfirm, Type = typeof(Button))] + public abstract class ClockBase : Control + { + protected const string ElementButtonConfirm = "PART_ButtonConfirm"; + + protected Button ButtonConfirm; + + protected bool AppliedTemplate; + + public event Action Confirmed; + + public event EventHandler> DisplayTimeChanged; + + public static readonly RoutedEvent SelectedTimeChangedEvent = + EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Direct, + typeof(EventHandler>), typeof(ClockBase)); + + public event EventHandler> SelectedTimeChanged + { + add => AddHandler(SelectedTimeChangedEvent, value); + remove => RemoveHandler(SelectedTimeChangedEvent, value); + } + + public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register( + "TimeFormat", typeof(string), typeof(ClockBase), new PropertyMetadata("HH:mm:ss")); + + public string TimeFormat + { + get => (string)GetValue(TimeFormatProperty); + set => SetValue(TimeFormatProperty, value); + } + + public static readonly DependencyProperty SelectedTimeProperty = DependencyProperty.Register( + "SelectedTime", typeof(DateTime?), typeof(ClockBase), new PropertyMetadata(default(DateTime?), OnSelectedTimeChanged)); + + private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ClockBase)d; + var v = (DateTime?)e.NewValue; + ctl.DisplayTime = v ?? DateTime.Now; + ctl.OnSelectedTimeChanged(new FunctionEventArgs(SelectedTimeChangedEvent, ctl) + { + Info = v + }); + } + + public DateTime? SelectedTime + { + get => (DateTime?) GetValue(SelectedTimeProperty); + set => SetValue(SelectedTimeProperty, value); + } + + public static readonly DependencyProperty DisplayTimeProperty = DependencyProperty.Register( + "DisplayTime", typeof(DateTime), typeof(ClockBase), + new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, + OnDisplayTimeChanged)); + + private static void OnDisplayTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ClockBase)d; + var v = (DateTime)e.NewValue; + ctl.Update(v); + ctl.OnDisplayTimeChanged(new FunctionEventArgs(v)); + } + + public DateTime DisplayTime + { + get => (DateTime)GetValue(DisplayTimeProperty); + set => SetValue(DisplayTimeProperty, value); + } + + internal static readonly DependencyProperty ShowConfirmButtonProperty = DependencyProperty.Register( + "ShowConfirmButton", typeof(bool), typeof(ClockBase), new PropertyMetadata(ValueBoxes.FalseBox)); + + internal bool ShowConfirmButton + { + get => (bool) GetValue(ShowConfirmButtonProperty); + set => SetValue(ShowConfirmButtonProperty, value); + } + + protected virtual void OnSelectedTimeChanged(FunctionEventArgs e) => RaiseEvent(e); + + protected virtual void OnDisplayTimeChanged(FunctionEventArgs e) + { + var handler = DisplayTimeChanged; + handler?.Invoke(this, e); + } + + protected void ButtonConfirm_OnClick(object sender, RoutedEventArgs e) + { + SelectedTime = DisplayTime; + Confirmed?.Invoke(); + } + + internal abstract void Update(DateTime time); + + protected void Clock_SelectedTimeChanged(object sender, FunctionEventArgs e) => SelectedTime = e.Info; + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/Clock/ListClock.cs b/src/Shared/HandyControl_Shared/Controls/Time/Clock/ListClock.cs new file mode 100644 index 00000000..80376a1d --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Time/Clock/ListClock.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Controls; + +namespace HandyControl.Controls +{ + [TemplatePart(Name = ElementHourList, Type = typeof(ListBox))] + [TemplatePart(Name = ElementMinuteList, Type = typeof(ListBox))] + [TemplatePart(Name = ElementSecondList, Type = typeof(ListBox))] + public class ListClock : ClockBase + { + #region Constants + + private const string ElementHourList = "PART_HourList"; + private const string ElementMinuteList = "PART_MinuteList"; + private const string ElementSecondList = "PART_SecondList"; + + #endregion Constants + + #region Data + + private ListBox _hourList; + + private ListBox _minuteList; + + private ListBox _secondList; + + #endregion Data + + public override void OnApplyTemplate() + { + AppliedTemplate = false; + if (ButtonConfirm != null) + { + ButtonConfirm.Click -= ButtonConfirm_OnClick; + } + + if (_hourList != null) + { + _hourList.SelectionChanged -= HourList_SelectionChanged; + } + + if (_minuteList != null) + { + _minuteList.SelectionChanged -= MinuteList_SelectionChanged; + } + + if (_secondList != null) + { + _secondList.SelectionChanged -= SecondList_SelectionChanged; + } + + base.OnApplyTemplate(); + + _hourList = GetTemplateChild(ElementHourList) as ListBox; + if (_hourList != null) + { + CreateItemsSource(_hourList, 24); + _hourList.SelectionChanged += HourList_SelectionChanged; + } + + _minuteList = GetTemplateChild(ElementMinuteList) as ListBox; + if (_minuteList != null) + { + CreateItemsSource(_minuteList, 60); + _minuteList.SelectionChanged += MinuteList_SelectionChanged; + } + + _secondList = GetTemplateChild(ElementSecondList) as ListBox; + if (_secondList != null) + { + CreateItemsSource(_secondList, 60); + _secondList.SelectionChanged += SecondList_SelectionChanged; + } + + ButtonConfirm = GetTemplateChild(ElementButtonConfirm) as Button; + + if (ButtonConfirm != null) + { + ButtonConfirm.Click += ButtonConfirm_OnClick; + } + + AppliedTemplate = true; + if (SelectedTime.HasValue) + { + Update(SelectedTime.Value); + } + else + { + DisplayTime = DateTime.Now; + Update(DisplayTime); + } + } + + private void HourList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update(); + + private void MinuteList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update(); + + private void SecondList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update(); + + private void CreateItemsSource(ItemsControl selector, int count) + { + var list = new List(); + for (int i = 0; i < count; i++) + { + list.Add(i.ToString("#00")); + } + + selector.ItemsSource = list; + } + + private void Update() + { + if (_hourList.SelectedIndex >= 0 && _hourList.SelectedIndex < 24 && + _minuteList.SelectedIndex >= 0 && _minuteList.SelectedIndex < 60 && + _secondList.SelectedIndex >= 0 && _secondList.SelectedIndex < 60) + { + var now = DateTime.Now; + DisplayTime = new DateTime(now.Year, now.Month, now.Day, _hourList.SelectedIndex, + _minuteList.SelectedIndex, _secondList.SelectedIndex); + } + } + + /// + /// 更新 + /// + /// + internal override void Update(DateTime time) + { + if (!AppliedTemplate) return; + + var h = time.Hour; + var m = time.Minute; + var s = time.Second; + + _hourList.SelectedIndex = h; + _minuteList.SelectedIndex = m; + _secondList.SelectedIndex = s; + + _hourList.ScrollIntoView(_hourList.SelectedItem); + _minuteList.ScrollIntoView(_minuteList.SelectedItem); + _secondList.ScrollIntoView(_secondList.SelectedItem); + + DisplayTime = time; + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs b/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs deleted file mode 100644 index 8cea4c60..00000000 --- a/src/Shared/HandyControl_Shared/Controls/Time/ItemsControlExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace HandyControl.Controls -{ - /// - /// ItemsControl扩展方法 - /// - public static class ItemsControlExtensions - { - /// - /// 平滑滚动至指定元素 - /// - /// - /// - public static void AnimateScrollIntoView(this ItemsControl itemsControl, object item) - { - ScrollViewer scrollViewer = FindVisualChild(itemsControl); - if (scrollViewer == null) - { - return; - } - - UIElement container = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as UIElement; - - if (container == null) - { - return; - } - - int index = itemsControl.ItemContainerGenerator.IndexFromContainer(container); - - //平滑滚动到元素所在位置 - //double toValue = scrollViewer.ScrollableHeight * ((double)index / itemsControl.Items.Count); - //平滑滚动,将选中的元素置顶 - double toValue = VisualTreeHelper.GetOffset(container).Y; - - DoubleAnimation verticalAnimation = new DoubleAnimation(); - verticalAnimation.From = scrollViewer.VerticalOffset; - verticalAnimation.To = toValue; - verticalAnimation.DecelerationRatio = .2; - verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(200)); - Storyboard storyboard = new Storyboard(); - storyboard.Children.Add(verticalAnimation); - Storyboard.SetTarget(verticalAnimation, scrollViewer); - Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(ScrollViewerBehavior.VerticalOffsetProperty)); - storyboard.Begin(); - } - - /// - /// 查找元素的子元素 - /// - /// 子元素类型 - /// - /// - public static T FindVisualChild(DependencyObject obj) where T : DependencyObject - { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) - { - DependencyObject child = VisualTreeHelper.GetChild(obj, i); - if (child != null && child is T) - return (T)child; - else - { - T childOfChild = FindVisualChild(child); - if (childOfChild != null) - return childOfChild; - } - } - return null; - } - } -} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs deleted file mode 100644 index 751bb887..00000000 --- a/src/Shared/HandyControl_Shared/Controls/Time/TimeButton.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; - -namespace HandyControl.Controls -{ - public class TimeButton : ListBoxItem - { - #region Private属性 - #endregion - - #region 依赖属性定义 - - #endregion - - #region 依赖属性set get - - #endregion - - #region Constructors - static TimeButton() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(TimeButton), new FrameworkPropertyMetadata(typeof(TimeButton))); - } - #endregion - - #region Override方法 - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - } - #endregion - - #region Private方法 - - #endregion - } -} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs deleted file mode 100644 index 9605dfc0..00000000 --- a/src/Shared/HandyControl_Shared/Controls/Time/TimePickerList.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; - -namespace HandyControl.Controls -{ - public class TimePickerList : Control - { - #region Private属性 - private TextBox PART_TextBox; - private TimeSelector PART_TimeSelector; - private Popup PART_Popup; - #endregion - - #region 依赖属性定义 - - #endregion - - #region 依赖属性set get - - #region TimeStringFormat - public string TimeStringFormat - { - get { return (string)GetValue(TimeStringFormatProperty); } - set { SetValue(TimeStringFormatProperty, value); } - } - - public static readonly DependencyProperty TimeStringFormatProperty = - DependencyProperty.Register("TimeStringFormat", typeof(string), typeof(TimePickerList), new PropertyMetadata("HH:mm:ss")); - #endregion - - #region SelectedTime - public DateTime? SelectedTime - { - get { return (DateTime?)GetValue(SelectedTimeProperty); } - set { SetValue(SelectedTimeProperty, value); } - } - - public static readonly DependencyProperty SelectedTimeProperty = - DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePickerList), new PropertyMetadata(null, SelectedTimeChangedCallback)); - - private static void SelectedTimeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - TimePickerList timePicker = d as TimePickerList; - DateTime dt = (DateTime)e.NewValue; - - timePicker.PART_TimeSelector.SelectedTime = dt; - } - #endregion - - #region DropDownHeight - - public double DropDownHeight - { - get { return (double)GetValue(DropDownHeightProperty); } - set { SetValue(DropDownHeightProperty, value); } - } - - public static readonly DependencyProperty DropDownHeightProperty = - DependencyProperty.Register("DropDownHeight", typeof(double), typeof(TimePickerList), new PropertyMetadata(168d)); - - #endregion - - #endregion - - #region Constructors - static TimePickerList() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePickerList), new FrameworkPropertyMetadata(typeof(TimePickerList))); - } - #endregion - - #region Override方法 - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.PART_TextBox = this.GetTemplateChild("PART_TextBox") as TextBox; - this.PART_TimeSelector = this.GetTemplateChild("PART_TimeSelector") as TimeSelector; - this.PART_Popup = this.GetTemplateChild("PART_Popup") as Popup; - if (this.PART_TimeSelector != null) - { - this.PART_TimeSelector.Owner = this; - this.PART_TimeSelector.SelectedTimeChanged += PART_TimeSelector_SelectedTimeChanged; - } - if (this.PART_Popup != null) - { - this.PART_Popup.Opened += PART_Popup_Opened; - } - } - - private void PART_Popup_Opened(object sender, EventArgs e) - { - this.PART_TimeSelector.SetButtonSelected(); - } - #endregion - - #region Private方法 - private void PART_TimeSelector_SelectedTimeChanged(object sender, RoutedPropertyChangedEventArgs e) - { - if (this.PART_TextBox != null && e.NewValue != null) - { - this.PART_TextBox.Text = e.NewValue.Value.ToString(this.TimeStringFormat); - this.SelectedTime = e.NewValue; - } - } - #endregion - } -} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs b/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs deleted file mode 100644 index e2eb030a..00000000 --- a/src/Shared/HandyControl_Shared/Controls/Time/TimeSelector.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace HandyControl.Controls -{ - public class TimeSelector : Control - { - private ObservableCollection HourButtons = new ObservableCollection(); - private ObservableCollection MinuteButtons = new ObservableCollection(); - private ObservableCollection SecondButtons = new ObservableCollection(); - - #region 控件内部元素 - private ListBox PART_Hour; - private ListBox PART_Minute; - private ListBox PART_Second; - #endregion - - #region 私有属性 - private int Hour = 0; - private int Minute = 0; - private int Second = 0; - #endregion - - #region Fields - public TimePickerList Owner { get; set; } - #endregion - - #region 事件定义 - - #region SelectedTimeChanged - public static readonly RoutedEvent SelectedTimeChangedEvent = EventManager.RegisterRoutedEvent("SelectedTimeChanged", - RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(TimeSelector)); - - public event RoutedPropertyChangedEventHandler SelectedTimeChanged - { - add - { - this.AddHandler(SelectedTimeChangedEvent, value); - } - remove - { - this.RemoveHandler(SelectedTimeChangedEvent, value); - } - } - - public virtual void OnSelectedTimeChanged(DateTime? oldValue, DateTime? newValue) - { - RoutedPropertyChangedEventArgs arg = new RoutedPropertyChangedEventArgs(oldValue, newValue, SelectedTimeChangedEvent); - this.RaiseEvent(arg); - } - #endregion - - #endregion - - #region 依赖属性set get - - #region SelectedTime - public DateTime? SelectedTime - { - get { return (DateTime?)GetValue(SelectedTimeProperty); } - set { SetValue(SelectedTimeProperty, value); } - } - - public static readonly DependencyProperty SelectedTimeProperty = - DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimeSelector), new PropertyMetadata(null, SelectedTimeChangedCallback)); - - private static void SelectedTimeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - TimeSelector timeSelector = d as TimeSelector; - DateTime dt = (DateTime)e.NewValue; - - timeSelector.SetButtonSelected(); - - timeSelector.OnSelectedTimeChanged((DateTime?)e.OldValue, (DateTime?)e.NewValue); - } - - public void SetButtonSelected() - { - if (!this.SelectedTime.HasValue) - { - return; - } - - this.Hour = this.SelectedTime.Value.Hour; - this.Minute = this.SelectedTime.Value.Minute; - this.Second = this.SelectedTime.Value.Second; - - if (this.PART_Hour != null) - { - for (int i = 0; i < this.PART_Hour.Items.Count; i++) - { - TimeButton timeButton = this.PART_Hour.Items[i] as TimeButton; - if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Hour))) - { - this.PART_Hour.SelectedIndex = i; - this.PART_Hour.AnimateScrollIntoView(timeButton); - break; - } - } - } - - if (this.PART_Minute != null) - { - for (int i = 0; i < this.PART_Minute.Items.Count; i++) - { - TimeButton timeButton = this.PART_Minute.Items[i] as TimeButton; - if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Minute))) - { - this.PART_Minute.SelectedIndex = i; - this.PART_Minute.AnimateScrollIntoView(timeButton); - break; - } - } - } - - if (this.PART_Second != null) - { - for (int i = 0; i < this.PART_Second.Items.Count; i++) - { - TimeButton timeButton = this.PART_Second.Items[i] as TimeButton; - if (Convert.ToString(timeButton.Content).Equals(Convert.ToString(this.SelectedTime.Value.Second))) - { - this.PART_Second.SelectedIndex = i; - this.PART_Second.AnimateScrollIntoView(timeButton); - break; - } - } - } - } - #endregion - - #region SelectedHour - public int? SelectedHour - { - get { return (int?)GetValue(SelectedHourProperty); } - set { SetValue(SelectedHourProperty, value); } - } - - public static readonly DependencyProperty SelectedHourProperty = - DependencyProperty.Register("SelectedHour", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedHourChanged)); - - private static void SelectedHourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - TimeSelector timeSelector = d as TimeSelector; - timeSelector.Hour = e.NewValue == null ? 0 : (int)e.NewValue; - timeSelector.SetSelectedTime(); - } - #endregion - - #region SelectedMinute - - public int? SelectedMinute - { - get { return (int?)GetValue(SelectedMinuteProperty); } - set { SetValue(SelectedMinuteProperty, value); } - } - - public static readonly DependencyProperty SelectedMinuteProperty = - DependencyProperty.Register("SelectedMinute", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedMinuteChanged)); - - private static void SelectedMinuteChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - TimeSelector timeSelector = d as TimeSelector; - - timeSelector.Minute = e.NewValue == null ? 0 : (int)e.NewValue; - timeSelector.SetSelectedTime(); - } - - #endregion - - #region SelectedSecond - - public int? SelectedSecond - { - get { return (int?)GetValue(SelectedSecondProperty); } - set { SetValue(SelectedSecondProperty, value); } - } - - public static readonly DependencyProperty SelectedSecondProperty = - DependencyProperty.Register("SelectedSecond", typeof(int?), typeof(TimeSelector), new PropertyMetadata(null, SelectedSecondChanged)); - - private static void SelectedSecondChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - TimeSelector timeSelector = d as TimeSelector; - - timeSelector.Second = e.NewValue == null ? 0 : (int)e.NewValue; - timeSelector.SetSelectedTime(); - } - - #endregion - - #region ItemHeight - public double ItemHeight - { - get { return (double)GetValue(ItemHeightProperty); } - set { SetValue(ItemHeightProperty, value); } - } - - public static readonly DependencyProperty ItemHeightProperty = - DependencyProperty.Register("ItemHeight", typeof(double), typeof(TimeSelector), new PropertyMetadata(28.0)); - #endregion - - #endregion - - #region Constructors - static TimeSelector() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(TimeSelector), new FrameworkPropertyMetadata(typeof(TimeSelector))); - } - #endregion - - #region Override方法 - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.PART_Hour = this.GetTemplateChild("PART_Hour") as ListBox; - this.PART_Minute = this.GetTemplateChild("PART_Minute") as ListBox; - this.PART_Second = this.GetTemplateChild("PART_Second") as ListBox; - - if (this.PART_Hour != null) - { - this.CreateHourButtons(); - this.PART_Hour.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(HourButton_Click), true); - } - - if (this.PART_Minute != null) - { - this.CreateMinuteButtons(); - this.PART_Minute.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(MinuteButton_Click), true); - } - - if (this.PART_Second != null) - { - this.CreateSecondButtons(); - this.PART_Second.AddHandler(ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(SecondButton_Click), true); - } - } - #endregion - - #region Private方法 - - private void MinuteButton_Click(object sender, RoutedEventArgs e) - { - TimeButton selectedItem = this.PART_Minute.SelectedItem as TimeButton; - if (selectedItem == null) - { - return; - } - this.SelectedMinute = Convert.ToInt32(selectedItem.DataContext); - this.PART_Minute.AnimateScrollIntoView(selectedItem); - } - - private void SecondButton_Click(object sender, RoutedEventArgs e) - { - TimeButton selectedItem = this.PART_Second.SelectedItem as TimeButton; - if (selectedItem == null) - { - return; - } - this.SelectedSecond = Convert.ToInt32(selectedItem.DataContext); - this.PART_Second.AnimateScrollIntoView(selectedItem); - } - - private void HourButton_Click(object sender, RoutedEventArgs e) - { - TimeButton selectedItem = this.PART_Hour.SelectedItem as TimeButton; - if (selectedItem == null) - { - return; - } - this.SelectedHour = Convert.ToInt32(selectedItem.DataContext); - this.PART_Hour.AnimateScrollIntoView(selectedItem); - } - - private void CreateHourButtons() - { - this.CreateItems(24, this.HourButtons); - this.CreateExtraItem(this.HourButtons); - this.PART_Hour.ItemsSource = this.HourButtons; - } - - private void CreateMinuteButtons() - { - this.CreateItems(60, this.MinuteButtons); - this.CreateExtraItem(this.MinuteButtons); - this.PART_Minute.ItemsSource = this.MinuteButtons; - } - - private void CreateSecondButtons() - { - this.CreateItems(60, this.SecondButtons); - this.CreateExtraItem(this.SecondButtons); - this.PART_Second.ItemsSource = this.SecondButtons; - } - - private void CreateItems(int itemsCount, ObservableCollection list) - { - for (int i = 0; i < itemsCount; i++) - { - TimeButton timeButton = new TimeButton(); - timeButton.SetValue(TimeButton.HeightProperty, this.ItemHeight); - timeButton.SetValue(TimeButton.DataContextProperty, i); - timeButton.SetValue(TimeButton.ContentProperty, (i < 10) ? "0" + i : i.ToString()); - timeButton.SetValue(TimeButton.IsSelectedProperty, false); - list.Add(timeButton); - } - } - - private void CreateExtraItem(ObservableCollection list) - { - double height = this.ItemHeight; - if (this.Owner != null) - { - height = this.Owner.DropDownHeight; - } - else - { - height = double.IsNaN(this.Height) ? height : this.Height; - } - - for (int i = 0; i < (height - this.ItemHeight) / this.ItemHeight; i++) - { - TimeButton timeButton = new TimeButton(); - timeButton.SetValue(TimeButton.HeightProperty, this.ItemHeight); - timeButton.SetValue(TimeButton.IsEnabledProperty, false); - timeButton.SetValue(TimeButton.IsSelectedProperty, false); - list.Add(timeButton); - } - } - - private DateTime GetDateTime(int hour, int minute, int second) - { - DateTime dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, hour, minute, second); - return dt; - } - - /// - /// 设置选中的时间 - /// - private void SetSelectedTime() - { - DateTime dt = this.GetDateTime(this.Hour, this.Minute, this.Second); - this.SelectedTime = dt; - } - #endregion - } - public class ScrollViewerBehavior - { - public static DependencyProperty VerticalOffsetProperty = - DependencyProperty.RegisterAttached("VerticalOffset", - typeof(double), - typeof(ScrollViewerBehavior), - new UIPropertyMetadata(0.0, OnVerticalOffsetChanged)); - - public static void SetVerticalOffset(FrameworkElement target, double value) - { - target.SetValue(VerticalOffsetProperty, value); - } - public static double GetVerticalOffset(FrameworkElement target) - { - return (double)target.GetValue(VerticalOffsetProperty); - } - private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) - { - ScrollViewer scrollViewer = target as ScrollViewer; - if (scrollViewer != null) - { - scrollViewer.ScrollToVerticalOffset((double)e.NewValue); - } - } - } -} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs b/src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs index 6a786fec..2a1aedb3 100644 --- a/src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs +++ b/src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs @@ -1,5 +1,6 @@ using System; using HandyControl.Controls; +using HandyControl.Tools; namespace HandyControl.Data { diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 801e85b4..4a434741 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -95,15 +95,13 @@ + + - - - - @@ -702,14 +700,6 @@ Designer MSBuild:Compile - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - Designer MSBuild:Compile diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Clock.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Clock.xaml index 21f81b18..c2051afd 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/Clock.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/Clock.xaml @@ -6,6 +6,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml index 56d1f56c..5a971e9d 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/Style.xaml @@ -63,8 +63,6 @@ - - \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml deleted file mode 100644 index ff291905..00000000 --- a/src/Shared/HandyControl_Shared/Themes/Styles/TimePickerList.xaml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml deleted file mode 100644 index 3dd43aaa..00000000 --- a/src/Shared/HandyControl_Shared/Themes/Styles/TimeSelector.xaml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs b/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs index 17e2219c..84586d8c 100644 --- a/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs +++ b/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs @@ -4,8 +4,9 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using HandyControl.Controls; +using HandyControl.Data; -namespace HandyControl.Data +namespace HandyControl.Tools { internal class ImageAnimator {