選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

249 行
8.3 KiB

  1. using BPA.UIControl.Commons.KnownBoxes;
  2. using System;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Controls.Primitives;
  8. namespace BPA.UIControl
  9. {
  10. /// <summary>
  11. /// 时钟
  12. /// </summary>
  13. [TemplatePart(Name = HourListPartName, Type = typeof(Selector))]
  14. [TemplatePart(Name = MinuteListPartName, Type = typeof(Selector))]
  15. [TemplatePart(Name = ConfirmPartName, Type = typeof(Button))]
  16. public class Clock : Control
  17. {
  18. /// <summary>
  19. /// 小时列表名称
  20. /// </summary>
  21. public const string HourListPartName = "PART_HourList";
  22. /// <summary>
  23. /// 分钟列表名称
  24. /// </summary>
  25. public const string MinuteListPartName = "PART_MinuteList";
  26. /// <summary>
  27. /// 确认按钮名称
  28. /// </summary>
  29. public const string ConfirmPartName = "PART_ConfirmButton";
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="Clock"/> class.
  32. /// </summary>
  33. static Clock()
  34. {
  35. DefaultStyleKeyProperty.OverrideMetadata(typeof(Clock), new FrameworkPropertyMetadata(typeof(Clock)));
  36. }
  37. /// <inheritdoc/>
  38. public override void OnApplyTemplate()
  39. {
  40. base.OnApplyTemplate();
  41. if (GetTemplateChild(ConfirmPartName) is Button confirmButton)
  42. {
  43. confirmButton.Click += ConfirmButton_Click;
  44. }
  45. Hours = new ObservableCollection<int>(Enumerable.Range(0, 24));
  46. Minutes = new ObservableCollection<int>(Enumerable.Range(0, 60));
  47. CurrentTime = new DateTime(DateTime.Now.TimeOfDay.Ticks);
  48. Hour = CurrentTime.Value.Hour;
  49. Minute = CurrentTime.Value.Minute;
  50. }
  51. #region 路由事件
  52. /// <summary>
  53. /// 选择时间改变事件
  54. /// </summary>
  55. public static readonly RoutedEvent SelectedTimeChangedEvent = EventManager.RegisterRoutedEvent(
  56. "SelectedTimeChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<DateTime?>), typeof(Clock));
  57. /// <summary>
  58. /// 选择时间改变事件处理
  59. /// </summary>
  60. public event RoutedPropertyChangedEventHandler<DateTime?> SelectedTimeChanged
  61. {
  62. add { AddHandler(SelectedTimeChangedEvent, value); }
  63. remove { RemoveHandler(SelectedTimeChangedEvent, value); }
  64. }
  65. /// <summary>
  66. /// 当前事件改变事件
  67. /// </summary>
  68. public static readonly RoutedEvent CurrentTimeChangedEvent = EventManager.RegisterRoutedEvent(
  69. "CurrentTimeChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<DateTime?>), typeof(Clock));
  70. /// <summary>
  71. /// 当前事件改变事件处理
  72. /// </summary>
  73. public event RoutedPropertyChangedEventHandler<DateTime?> CurrentTimeChanged
  74. {
  75. add { AddHandler(CurrentTimeChangedEvent, value); }
  76. remove { RemoveHandler(CurrentTimeChangedEvent, value); }
  77. }
  78. #endregion
  79. #region 依赖属性
  80. /// <summary>
  81. /// 时集合
  82. /// </summary>
  83. internal static readonly DependencyProperty HoursProperty = DependencyProperty.Register(
  84. "Hours", typeof(ObservableCollection<int>), typeof(Clock), new PropertyMetadata(null));
  85. /// <summary>
  86. /// 时集合
  87. /// </summary>
  88. internal ObservableCollection<int> Hours
  89. {
  90. get { return (ObservableCollection<int>)GetValue(HoursProperty); }
  91. set { SetValue(HoursProperty, value); }
  92. }
  93. /// <summary>
  94. /// 时
  95. /// </summary>
  96. public static readonly DependencyProperty HourProperty = DependencyProperty.Register(
  97. "Hour", typeof(int), typeof(Clock), new PropertyMetadata(0, OnItemSeletedChanged));
  98. /// <summary>
  99. /// 时
  100. /// </summary>
  101. public int Hour
  102. {
  103. get { return (int)GetValue(HourProperty); }
  104. set { SetValue(HourProperty, value); }
  105. }
  106. /// <summary>
  107. /// 分集合
  108. /// </summary>
  109. internal static readonly DependencyProperty MinutesProperty = DependencyProperty.Register(
  110. "Minutes", typeof(ObservableCollection<int>), typeof(Clock), new PropertyMetadata(null));
  111. /// <summary>
  112. /// 分集合
  113. /// </summary>
  114. internal ObservableCollection<int> Minutes
  115. {
  116. get { return (ObservableCollection<int>)GetValue(MinutesProperty); }
  117. set { SetValue(MinutesProperty, value); }
  118. }
  119. /// <summary>
  120. /// 分
  121. /// </summary>
  122. public static readonly DependencyProperty MinuteProperty = DependencyProperty.Register(
  123. "Minute", typeof(int), typeof(Clock), new PropertyMetadata(0, OnItemSeletedChanged));
  124. /// <summary>
  125. /// 分
  126. /// </summary>
  127. public int Minute
  128. {
  129. get { return (int)GetValue(MinuteProperty); }
  130. set { SetValue(MinuteProperty, value); }
  131. }
  132. /// <summary>
  133. /// 选中时间
  134. /// </summary>
  135. public static readonly DependencyProperty SelectedTimeProperty = DependencyProperty.Register(
  136. "SelectedTime", typeof(DateTime?), typeof(Clock), new PropertyMetadata(default(DateTime), OnSelectTimeChanged));
  137. private static void OnSelectTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  138. {
  139. var clock = (Clock)d;
  140. if (clock.SelectedTime != null)
  141. {
  142. clock.Hour = clock.SelectedTime.Value.Hour;
  143. clock.Minute = clock.SelectedTime.Value.Minute;
  144. }
  145. }
  146. /// <summary>
  147. /// 选中时间
  148. /// </summary>
  149. public DateTime? SelectedTime
  150. {
  151. get { return (DateTime?)GetValue(SelectedTimeProperty); }
  152. set { SetValue(SelectedTimeProperty, value); }
  153. }
  154. /// <summary>
  155. /// 当前时间
  156. /// </summary>
  157. public static readonly DependencyProperty CurrentTimeProperty =
  158. DependencyProperty.Register("CurrentTime", typeof(DateTime?), typeof(Clock), new PropertyMetadata(default(DateTime?)));
  159. /// <summary>
  160. /// 当前时间
  161. /// </summary>
  162. public DateTime? CurrentTime
  163. {
  164. get { return (DateTime?)GetValue(CurrentTimeProperty); }
  165. set { SetValue(CurrentTimeProperty, value); }
  166. }
  167. /// <summary>
  168. /// 是否显示确认按钮
  169. /// </summary>
  170. public static readonly DependencyProperty IsShowConfirmButtonProperty =
  171. DependencyProperty.Register("IsShowConfirmButton", typeof(bool), typeof(Clock), new PropertyMetadata(BooleanBoxes.TrueBox));
  172. /// <summary>
  173. /// 是否显示确认按钮
  174. /// </summary>
  175. public bool IsShowConfirmButton
  176. {
  177. get { return (bool)GetValue(IsShowConfirmButtonProperty); }
  178. set { SetValue(IsShowConfirmButtonProperty, BooleanBoxes.Box(value)); }
  179. }
  180. #endregion
  181. /// <summary>
  182. /// 时间选择改变
  183. /// </summary>
  184. private static void OnItemSeletedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  185. {
  186. var clock = d as Clock;
  187. if (!clock.IsLoaded)
  188. {
  189. return;
  190. }
  191. clock.CurrentTime = Convert.ToDateTime($"{clock.Hour}:{clock.Minute}");
  192. if (e.NewValue != null)
  193. {
  194. var args = new RoutedPropertyChangedEventArgs<DateTime?>(DateTime.Now, (DateTime)clock.CurrentTime);
  195. args.RoutedEvent = CurrentTimeChangedEvent;
  196. clock.RaiseEvent(args);
  197. }
  198. }
  199. /// <summary>
  200. /// 确认时间
  201. /// </summary>
  202. private void ConfirmButton_Click(object sender, RoutedEventArgs e)
  203. {
  204. var oldTime = SelectedTime;
  205. var newTime = CurrentTime;
  206. SelectedTime = CurrentTime;
  207. var args = new RoutedPropertyChangedEventArgs<DateTime?>(oldTime, newTime);
  208. args.RoutedEvent = SelectedTimeChangedEvent;
  209. RaiseEvent(args);
  210. }
  211. }
  212. }