以下控件采用https://www.cnblogs.com/cssmystyle/archive/2011/01/17/1937361.html部分代码

以下控件采用https://www.cnblogs.com/xiaomingg/p/11180355.html部分代码

TimeSpanBox 效果如下,用于选择时间的长度,年最大值99,月最大值11,日最大值30,时最大值23,分最大值59,秒最大值59

第一步,新建WPF用户TimepanBox

  1. <UserControl x:Class="WPFApp.Controls.TimeSpanBox.TimeSpanBox"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:local="clr-namespace:WPFApp.Controls.TimeSpanBox"
  7. BorderBrush="Gray" BorderThickness="1" mc:Ignorable="d" Focusable="False"
  8. d:DesignHeight="25" d:DesignWidth="200">
  9. <UserControl.Resources>
  10. <ControlTemplate x:Key="UPBtnTemplate" TargetType="{x:Type RepeatButton}">
  11. <Border BorderThickness="0">
  12. <Border.Background>
  13. <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="1">
  14. <GradientStop Color="#FFF9FAFB" Offset="0" />
  15. <GradientStop Color="#FFC4CCD4" Offset="0.973" />
  16. </LinearGradientBrush>
  17. </Border.Background>
  18. <ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding Button.Content}" VerticalAlignment="Center"/>
  19. </Border>
  20. <ControlTemplate.Triggers>
  21. <Trigger Property="IsPressed" Value="True">
  22. <Setter Property="RenderTransform">
  23. <Setter.Value>
  24. <TranslateTransform X=".5" Y=".3"/>
  25. </Setter.Value>
  26. </Setter>
  27. </Trigger>
  28. </ControlTemplate.Triggers>
  29. </ControlTemplate>
  30. <ControlTemplate x:Key="DownBtnTemplate" TargetType="{x:Type RepeatButton}">
  31. <Border BorderThickness="0">
  32. <Border.Background>
  33. <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="1">
  34. <GradientStop Color="#FFC4CCD4" Offset="0.973" />
  35. <GradientStop Color="#FFF9FAFB" Offset="0" />
  36. </LinearGradientBrush>
  37. </Border.Background>
  38. <ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding Button.Content}" VerticalAlignment="Center"/>
  39. </Border>
  40. <ControlTemplate.Triggers>
  41. <Trigger Property="IsPressed" Value="True">
  42. <Setter Property="RenderTransform">
  43. <Setter.Value>
  44. <TranslateTransform X=".5" Y=".3"/>
  45. </Setter.Value>
  46. </Setter>
  47. </Trigger>
  48. </ControlTemplate.Triggers>
  49. </ControlTemplate>
  50. </UserControl.Resources>
  51. <Grid Background="White">
  52. <Grid.ColumnDefinitions>
  53. <ColumnDefinition/>
  54. <ColumnDefinition Width="auto"/>
  55. <ColumnDefinition/>
  56. <ColumnDefinition Width="auto"/>
  57. <ColumnDefinition/>
  58. <ColumnDefinition Width="auto"/>
  59. <ColumnDefinition/>
  60. <ColumnDefinition Width="auto"/>
  61. <ColumnDefinition/>
  62. <ColumnDefinition Width="auto"/>
  63. <ColumnDefinition/>
  64. <ColumnDefinition Width="auto"/>
  65. <ColumnDefinition Width="auto"/>
  66. </Grid.ColumnDefinitions>
  67. <TextBox Grid.Column="0" BorderBrush="Transparent" BorderThickness="0" x:Name="txtYear" VerticalContentAlignment="Center"
  68. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  69. <TextBlock Text="年" Grid.Column="1" VerticalAlignment="Center" x:Name="txtbYear"/>
  70. <TextBox Grid.Column="2" BorderBrush="Transparent" BorderThickness="0" x:Name="txtMonth" VerticalContentAlignment="Center"
  71. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  72. <TextBlock Text="月" Grid.Column="3" VerticalAlignment="Center" x:Name="txtbMonth"/>
  73. <TextBox Grid.Column="4" BorderBrush="Transparent" BorderThickness="0" x:Name="txtDay" VerticalContentAlignment="Center"
  74. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  75. <TextBlock Text="天" Grid.Column="5" VerticalAlignment="Center" x:Name="txtbDay"/>
  76. <TextBox Grid.Column="6" BorderBrush="Transparent" BorderThickness="0" x:Name="txtHour" VerticalContentAlignment="Center"
  77. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  78. <TextBlock Text="时" Grid.Column="7" VerticalAlignment="Center" x:Name="txtbHour"/>
  79. <TextBox Grid.Column="8" BorderBrush="Transparent" BorderThickness="0" x:Name="txtMinute" VerticalContentAlignment="Center"
  80. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  81. <TextBlock Text="分" Grid.Column="9" VerticalAlignment="Center" x:Name="txtbMinute"/>
  82. <TextBox Grid.Column="10" BorderBrush="Transparent" BorderThickness="0" x:Name="txtSecound" VerticalContentAlignment="Center"
  83. InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
  84. <TextBlock Text="秒" Grid.Column="11" VerticalAlignment="Center" x:Name="txtbSecound"/>
  85. <UniformGrid Grid.Column="12" Rows="2" x:Name="gridShow" Margin="1,0,0,0">
  86. <RepeatButton Padding="0" Width="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Focusable="False"
  87. VerticalContentAlignment="Center" Template="{StaticResource UPBtnTemplate}" Command="{x:Static local:TimeSpanBox.IncreaseCommand}">
  88. <Path Height="6" Width="12" Stretch="Fill" Opacity="1" Fill="#FF554646"
  89. Data="M 666.5,597 C666.5,597 678.5,597 678.5,597 678.5,597 672.5,591 672.5,591 672.5,591 666.5,597 666.5,597 z"/>
  90. </RepeatButton>
  91. <RepeatButton Padding="0" Width="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Focusable="False"
  92. VerticalContentAlignment="Center" Template="{StaticResource DownBtnTemplate}" Command="{x:Static local:TimeSpanBox.DecreaseCommand}">
  93. <Path Height="6" Width="12" Stretch="Fill" Opacity="1" Fill="#FF554646"
  94. Data="M 666.5,609 C666.5,609 678.5,609 678.5,609 678.5,609 672.5,615 672.5,615 672.5,615 666.5,609 666.5,609 z"/>
  95. </RepeatButton>
  96. </UniformGrid>
  97. </Grid>
  98. </UserControl>

对应自定义用户控件的后台代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14.  
  15. namespace WPFApp.Controls.TimeSpanBox
  16. {
  17. public partial class TimeSpanBox : UserControl
  18. {
  19. private TextBox previousFocus = null;
  20. public TimeSpanBox()
  21. {
  22. InitializeComponent();
  23.  
  24. MouseButtonEventHandler PreviewMouseDown = (o1, e1) =>
  25. {
  26. TextBox textbox = o1 as TextBox;
  27. if (textbox != null)
  28. {
  29. textbox.Focus();
  30. e1.Handled = true;
  31. }
  32. };
  33. txtYear.PreviewMouseDown += PreviewMouseDown;
  34. txtMonth.PreviewMouseDown += PreviewMouseDown;
  35. txtDay.PreviewMouseDown += PreviewMouseDown;
  36. txtHour.PreviewMouseDown += PreviewMouseDown;
  37. txtMinute.PreviewMouseDown += PreviewMouseDown;
  38. txtSecound.PreviewMouseDown += PreviewMouseDown;
  39.  
  40. RoutedEventHandler GotFocus = (o1, e1) =>
  41. {
  42. TextBox txt = o1 as TextBox;
  43. if (txt != null)
  44. {
  45. txt.SelectAll();
  46. txt.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFBFEDF1"));
  47. txt.Foreground = new SolidColorBrush(Colors.Black);
  48. txt.PreviewMouseDown -= new MouseButtonEventHandler(PreviewMouseDown);
  49. }
  50. previousFocus = txt;
  51. };
  52. txtYear.GotFocus += GotFocus;
  53. txtMonth.GotFocus += GotFocus;
  54. txtDay.GotFocus += GotFocus;
  55. txtHour.GotFocus += GotFocus;
  56. txtMinute.GotFocus += GotFocus;
  57. txtSecound.GotFocus += GotFocus;
  58.  
  59. RoutedEventHandler LostFocus = (o1, e1) =>
  60. {
  61. var textBox = o1 as TextBox;
  62. if (textBox != null)
  63. {
  64. textBox.Background = new SolidColorBrush(Colors.Transparent);
  65. textBox.Foreground = new SolidColorBrush(Colors.Black);
  66. textBox.PreviewMouseDown += new MouseButtonEventHandler(PreviewMouseDown);
  67. }
  68. };
  69. txtYear.LostFocus += LostFocus;
  70. txtMonth.LostFocus += LostFocus;
  71. txtDay.LostFocus += LostFocus;
  72. txtHour.LostFocus += LostFocus;
  73. txtMinute.LostFocus += LostFocus;
  74. txtSecound.LostFocus += LostFocus;
  75.  
  76. KeyEventHandler KeyDowm = (o1, e1) =>
  77. {
  78. TextBox txt = o1 as TextBox;
  79. if (e1.Key == Key.Enter || (e1.Key == Key.Right && txt.SelectionStart == txt.Text.Length))
  80. {
  81. FocusNextText(txt);
  82. }
  83. else if (((e1.Key == Key.Delete || e1.Key == Key.Back) && (txt.Text == "0" || string.IsNullOrEmpty(txt.Text))) ||
  84. (txt.SelectionStart == 0 && e1.Key == Key.Left)
  85. )
  86. {
  87. e1.Handled = true;
  88. if (!(txt.SelectionStart == 0 && e1.Key == Key.Left))
  89. txt.Text = "0";
  90. FocusPreviousText(txt);
  91. }
  92. };
  93.  
  94. txtYear.PreviewKeyDown += KeyDowm;
  95. txtMonth.PreviewKeyDown += KeyDowm;
  96. txtDay.PreviewKeyDown += KeyDowm;
  97. txtHour.PreviewKeyDown += KeyDowm;
  98. txtMinute.PreviewKeyDown += KeyDowm;
  99. txtSecound.PreviewKeyDown += KeyDowm;
  100.  
  101. txtYear.TextChanged += TextYear_Changed;
  102. txtMonth.TextChanged += txtMonth_Changed;
  103. txtDay.TextChanged += txtDay_Changed;
  104. txtHour.TextChanged += txtHour_Changed;
  105. txtMinute.TextChanged += txtMinute_Changed;
  106. txtSecound.TextChanged += txtSecound_Changed;
  107.  
  108. txtbYear.MouseLeftButtonDown += (o1, e1) => { txtYear.Focus(); txtYear.SelectAll(); };
  109. txtbMonth.MouseLeftButtonDown += (o1, e1) => { txtMonth.Focus(); txtMonth.SelectAll(); };
  110. txtbDay.MouseLeftButtonDown += (o1, e1) => { txtDay.Focus(); txtDay.SelectAll(); };
  111. txtbHour.MouseLeftButtonDown += (o1, e1) => { txtHour.Focus(); txtHour.SelectAll(); };
  112. txtbMinute.MouseLeftButtonDown += (o1, e1) => { txtMinute.Focus(); txtMinute.SelectAll(); };
  113. txtbSecound.MouseLeftButtonDown += (o1, e1) => { txtSecound.Focus(); txtSecound.SelectAll(); };
  114.  
  115. this.SetTextBoxBindingText(this.txtYear, "YearText");
  116. this.SetTextBoxBindingText(this.txtMonth, "MonthText");
  117. this.SetTextBoxBindingText(this.txtDay, "DayText");
  118. this.SetTextBoxBindingText(this.txtHour, "HourText");
  119. this.SetTextBoxBindingText(this.txtMinute, "MinuteText");
  120. this.SetTextBoxBindingText(this.txtSecound, "SecoundText");
  121. }
  122. private void SetTextBoxBindingText(TextBox targetTxt,string bindingPath)
  123. {
  124. Binding binding = new Binding(bindingPath);
  125. binding.Source = this;
  126. binding.Mode = BindingMode.TwoWay;
  127. binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
  128. targetTxt.SetBinding(TextBox.TextProperty, binding);
  129. }
  130.  
  131. #region 注册路由命令
  132. #region 注册鼠标左键按下事件
  133. static TimeSpanBox()
  134. {
  135. InitializeCommands();
  136. //EventManager.RegisterClassHandler(typeof(TimeSpanBox),
  137. // Mouse.MouseDownEvent, new MouseButtonEventHandler(TimeSpanBox.OnMouseLeftButtonDown), true);
  138. }
  139. private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  140. {
  141. TimeSpanBox control = (TimeSpanBox)sender;
  142. //如果某人点击控件的部分只,但是该控件没有聚焦,
  143. //本空间需要获取焦点来处理正确处理键盘
  144. if (!control.IsKeyboardFocusWithin)//获取一个值,该值指示键盘焦点是否处于元素边界内的任何位置(包括键盘焦点是否位于任何可视子元素的边界内)。
  145. {
  146. e.Handled = control.Focus() || e.Handled;
  147. }
  148. }
  149. #endregion
  150.  
  151. private static RoutedCommand m_IncreaseCommand;
  152. private static RoutedCommand m_DecreaseCommand;
  153. public static RoutedCommand IncreaseCommand
  154. {
  155. get
  156. {
  157. return m_IncreaseCommand;
  158. }
  159. }
  160. public static RoutedCommand DecreaseCommand
  161. {
  162. get
  163. {
  164. return m_DecreaseCommand;
  165. }
  166. }
  167. private static void InitializeCommands()
  168. {
  169. m_IncreaseCommand = new RoutedCommand("IncreaseCommand", typeof(TimeSpanBox));
  170. CommandManager.RegisterClassCommandBinding(typeof(TimeSpanBox), new CommandBinding(m_IncreaseCommand, OnIncreaseCommand));
  171. CommandManager.RegisterClassInputBinding(typeof(TimeSpanBox), new InputBinding(m_IncreaseCommand, new KeyGesture(Key.Up)));
  172.  
  173. m_DecreaseCommand = new RoutedCommand("DecreaseCommand", typeof(TimeSpanBox));
  174. CommandManager.RegisterClassCommandBinding(typeof(TimeSpanBox), new CommandBinding(m_DecreaseCommand, OnDecreaseCommand));
  175. CommandManager.RegisterClassInputBinding(typeof(TimeSpanBox), new InputBinding(m_DecreaseCommand, new KeyGesture(Key.Down)));
  176. }
  177.  
  178. private static void OnDecreaseCommand(object sender, ExecutedRoutedEventArgs e)
  179. {
  180. TimeSpanBox control = sender as TimeSpanBox;
  181. if (control != null && control.previousFocus != null)
  182. {
  183. if (control.previousFocus == control.txtYear)
  184. {
  185. control.Year = Math.Max(0, control.Year - 1);
  186. control.txtYear.SelectAll();
  187. }
  188. else if (control.previousFocus == control.txtMonth)
  189. {
  190. control.Month = Math.Max(0, control.Month - 1);
  191. control.txtMonth.SelectAll();
  192. }
  193. else if (control.previousFocus == control.txtDay)
  194. {
  195. control.Day = Math.Max(0, control.Day - 1);
  196. control.txtDay.SelectAll();
  197. }
  198. else if (control.previousFocus == control.txtHour)
  199. {
  200. control.Hour = Math.Max(0, control.Hour - 1);
  201. control.txtHour.SelectAll();
  202. }
  203. else if (control.previousFocus == control.txtMinute)
  204. {
  205. control.Minutes = Math.Max(0, control.Minutes - 1);
  206. control.txtMinute.SelectAll();
  207. }
  208. else if (control.previousFocus == control.txtSecound)
  209. {
  210. control.Secound = Math.Max(0, control.Secound - 1);
  211. control.txtSecound.SelectAll();
  212. }
  213. }
  214. }
  215.  
  216. private static void OnIncreaseCommand(object sender, ExecutedRoutedEventArgs e)
  217. {
  218. TimeSpanBox control = sender as TimeSpanBox;
  219. if (control != null)
  220. {
  221. if (control.previousFocus == control.txtYear)
  222. {
  223. control.Year = Math.Min(99, control.Year + 1);
  224. control.txtYear.SelectAll();
  225. }
  226. else if (control.previousFocus == control.txtMonth)
  227. {
  228. control.Month = Math.Min(11, control.Month + 1);
  229. control.txtMonth.SelectAll();
  230. }
  231. else if (control.previousFocus == control.txtDay)
  232. {
  233. control.Day = Math.Min(30, control.Day + 1);
  234. control.txtDay.SelectAll();
  235. }
  236. else if (control.previousFocus == control.txtHour)
  237. {
  238. control.Hour = Math.Min(23, control.Hour + 1);
  239. control.txtHour.SelectAll();
  240. }
  241. else if (control.previousFocus == control.txtMinute)
  242. {
  243. control.Minutes = Math.Min(59, control.Minutes + 1);
  244. control.txtMinute.SelectAll();
  245. }
  246. else if (control.previousFocus == control.txtSecound)
  247. {
  248. control.Secound = Math.Min(59, control.Secound + 1);
  249. control.txtSecound.SelectAll();
  250. }
  251. }
  252. }
  253. #endregion
  254.  
  255. #region 跳转到上个文本框
  256. private void FocusNextText(TextBox currTxt)
  257. {
  258. TextBox[] textboxArray = new TextBox[] { txtYear, txtMonth, txtDay, txtHour, txtMinute, txtSecound };
  259. bool[] isVisibleArray = new bool[] { IsYearVisible, IsMonthVisible, IsDayVisible, IsHourVisible, IsMinuteVisible, IsSecoundVisible };
  260.  
  261. int index = Array.IndexOf(textboxArray, currTxt);
  262. if (index != -1)
  263. {
  264. var findTxt = textboxArray.Skip(index + 1).FirstOrDefault(txt => isVisibleArray[Array.IndexOf(textboxArray, txt)]);
  265. if (findTxt != null)
  266. {
  267. findTxt.Focus();
  268. }
  269. }
  270. }
  271. #endregion
  272. #region 跳转到下个文本框
  273. private void FocusPreviousText(TextBox currTxt)
  274. {
  275. TextBox[] textboxArray = new TextBox[] { txtYear, txtMonth, txtDay, txtHour, txtMinute, txtSecound };
  276. bool[] isVisibleArray = new bool[] { IsYearVisible, IsMonthVisible, IsDayVisible, IsHourVisible, IsMinuteVisible, IsSecoundVisible };
  277. int index = Array.IndexOf(textboxArray, currTxt);
  278. if (index != -1)
  279. {
  280. var findTxt = textboxArray.Take(index).Reverse().FirstOrDefault(txt => isVisibleArray[Array.IndexOf(textboxArray, txt)]);
  281. if (findTxt != null)
  282. {
  283. findTxt.Focus();
  284. }
  285. }
  286. }
  287. #endregion
  288.  
  289. #region 年份改变
  290. private bool CanRaiseTxtChaned_Year_AttachDP = true;
  291. private void TextYear_Changed(object sender, TextChangedEventArgs e)
  292. {
  293. string year = txtYear.Text;
  294. if (string.IsNullOrEmpty(year))
  295. {
  296. SetYear(0);
  297. if (txtYear.IsFocused == true)
  298. txtYear.SelectAll();
  299. }
  300. else
  301. {
  302. int newYear = 0;
  303. bool result = int.TryParse(year, out newYear);
  304. if (result == true && newYear >= 0 && this.Year != newYear)
  305. {
  306. if (newYear > 99)
  307. {
  308. SetText_Year("99");
  309. SetYear(99);
  310. txtMonth.Focus();
  311. }
  312. else
  313. {
  314. SetText_Year(newYear.ToString());
  315. SetYear(newYear);
  316. }
  317. if (txtYear.Text.Length == 2)
  318. FocusNextText(txtYear);
  319. }
  320. else
  321. {
  322. SetYear(0);
  323. SetText_Year("0");
  324. }
  325. }
  326. }
  327. private void SetText_Year(string newValue)
  328. {
  329. txtYear.TextChanged -= TextYear_Changed;
  330. txtYear.Text = newValue;
  331. txtYear.TextChanged += TextYear_Changed;
  332. }
  333. private void SetYear(int year)
  334. {
  335. CanRaiseTxtChaned_Year_AttachDP = false;
  336. this.Year = year;
  337. CanRaiseTxtChaned_Year_AttachDP = true;
  338. }
  339. #endregion
  340. #region 月份改变
  341. private bool CanRaiseTxtChaned_Month_AttachDP = true;
  342. private void txtMonth_Changed(object sender, TextChangedEventArgs e)
  343. {
  344. string month = txtMonth.Text;
  345. if (string.IsNullOrEmpty(month))
  346. {
  347. SetMonth(0);
  348. if (txtMonth.IsFocused == true)
  349. txtMonth.SelectAll();
  350. }
  351. else
  352. {
  353. int newMonth = 0;
  354. bool result = int.TryParse(month, out newMonth);
  355. if (result == true && newMonth >= 0 && this.Month != newMonth)
  356. {
  357. if (newMonth > 11)
  358. {
  359. SetText_Month("11");
  360. SetMonth(11);
  361. txtDay.Focus();
  362. }
  363. else
  364. {
  365. SetText_Month(newMonth.ToString());
  366. SetMonth(newMonth);
  367. }
  368. if (txtMonth.Text.Length == 2)
  369. FocusNextText(txtMonth);
  370. }
  371. else
  372. {
  373. SetMonth(0);
  374. SetText_Month("0");
  375. }
  376. }
  377. }
  378. private void SetText_Month(string newValue)
  379. {
  380. txtMonth.TextChanged -= txtMonth_Changed;
  381. txtMonth.Text = newValue;
  382. txtMonth.TextChanged += txtMonth_Changed;
  383. }
  384. private void SetMonth(int month)
  385. {
  386. CanRaiseTxtChaned_Month_AttachDP = false;
  387. this.Month = month;
  388. CanRaiseTxtChaned_Month_AttachDP = true;
  389. }
  390. #endregion
  391. #region 日改变
  392. private bool CanRaiseTxtChaned_Day_AttachDP = true;
  393. private void txtDay_Changed(object sender, TextChangedEventArgs e)
  394. {
  395. string day = txtDay.Text;
  396. if (string.IsNullOrEmpty(day))
  397. {
  398. SetDay(0);
  399. if (txtDay.IsFocused == true)
  400. txtDay.SelectAll();
  401. }
  402. else
  403. {
  404. int newDay = 0;
  405. bool result = int.TryParse(day, out newDay);
  406. if (result == true && newDay >= 0 && this.Day != newDay)
  407. {
  408. if (newDay > 30)
  409. {
  410. SetText_Day("30");
  411. SetDay(30);
  412. txtHour.Focus();
  413. }
  414. else
  415. {
  416. SetText_Day(newDay.ToString());
  417. SetDay(newDay);
  418. }
  419. if (txtDay.Text.Length == 2)
  420. FocusNextText(txtDay);
  421. }
  422. else
  423. {
  424. SetDay(0);
  425. SetText_Day("0");
  426. }
  427. }
  428. }
  429. private void SetText_Day(string newValue)
  430. {
  431. txtDay.TextChanged -= txtDay_Changed;
  432. txtDay.Text = newValue;
  433. txtDay.TextChanged += txtDay_Changed;
  434. }
  435. private void SetDay(int day)
  436. {
  437. CanRaiseTxtChaned_Day_AttachDP = false;
  438. this.Day = day;
  439. CanRaiseTxtChaned_Day_AttachDP = true;
  440. }
  441. #endregion
  442. #region 时改变
  443. private bool CanRaiseTxtChaned_Hour_AttachDP = true;
  444. private void txtHour_Changed(object sender, TextChangedEventArgs e)
  445. {
  446. string hour = txtHour.Text;
  447. if (string.IsNullOrEmpty(hour))
  448. {
  449. SetDay(0);
  450. if (txtHour.IsFocused == true)
  451. txtHour.SelectAll();
  452. }
  453. else
  454. {
  455. int newHour = 0;
  456. bool result = int.TryParse(hour, out newHour);
  457. if (result == true && newHour >= 0 && this.Hour != newHour)
  458. {
  459. if (newHour > 23)
  460. {
  461. SetText_Hour("23");
  462. SetHour(23);
  463. txtMinute.Focus();
  464. }
  465. else
  466. {
  467. SetText_Hour(newHour.ToString());
  468. SetHour(newHour);
  469. }
  470. if (txtHour.Text.Length == 2)
  471. FocusNextText(txtHour);
  472. }
  473. else
  474. {
  475. SetHour(0);
  476. SetText_Hour("0");
  477. }
  478. }
  479. }
  480. private void SetText_Hour(string newValue)
  481. {
  482. txtHour.TextChanged -= txtHour_Changed;
  483. txtHour.Text = newValue;
  484. txtHour.TextChanged += txtHour_Changed;
  485. }
  486. private void SetHour(int hour)
  487. {
  488. CanRaiseTxtChaned_Hour_AttachDP = false;
  489. this.Hour = hour;
  490. CanRaiseTxtChaned_Hour_AttachDP = true;
  491. }
  492. #endregion
  493. #region 分改变
  494. private bool CanRaiseTxtChaned_Minute_AttachDP = true;
  495. private void txtMinute_Changed(object sender, TextChangedEventArgs e)
  496. {
  497. string minute = txtMinute.Text;
  498. if (string.IsNullOrEmpty(minute))
  499. {
  500. SetMinute(0);
  501. if (txtMinute.IsFocused == true)
  502. txtMinute.SelectAll();
  503. }
  504. else
  505. {
  506. int newMinute = 0;
  507. bool result = int.TryParse(minute, out newMinute);
  508. if (result == true && newMinute >= 0 && this.Minutes != newMinute)
  509. {
  510. if (newMinute > 59)
  511. {
  512. SetText_Minute("59");
  513. SetMinute(59);
  514. txtSecound.Focus();
  515. }
  516. else
  517. {
  518. SetText_Minute(newMinute.ToString());
  519. SetMinute(newMinute);
  520. }
  521. if (txtMinute.Text.Length == 2)
  522. FocusNextText(txtMinute);
  523. }
  524. else
  525. {
  526. SetMinute(0);
  527. SetText_Minute("0");
  528. }
  529. }
  530. }
  531. private void SetText_Minute(string newValue)
  532. {
  533. txtMinute.TextChanged -= txtMinute_Changed;
  534. txtMinute.Text = newValue;
  535. txtMinute.TextChanged += txtMinute_Changed;
  536. }
  537. private void SetMinute(int Minute)
  538. {
  539. CanRaiseTxtChaned_Minute_AttachDP = false;
  540. this.Minutes = Minute;
  541. CanRaiseTxtChaned_Minute_AttachDP = true;
  542. }
  543. #endregion
  544. #region 秒改变
  545. private bool CanRaiseTxtChaned_Secound_AttachDP = true;
  546. private void txtSecound_Changed(object sender, TextChangedEventArgs e)
  547. {
  548. string secound = txtSecound.Text;
  549. if (string.IsNullOrEmpty(secound))
  550. {
  551. SetSecound(0);
  552. if (txtSecound.IsFocused == true)
  553. txtSecound.SelectAll();
  554. }
  555. else
  556. {
  557. int newSecound = 0;
  558. bool result = int.TryParse(secound, out newSecound);
  559. if (result == true && newSecound >= 0 && this.Secound != newSecound)
  560. {
  561. if (newSecound > 59)
  562. {
  563. SetText_Secound("59");
  564. SetSecound(59);
  565. txtSecound.SelectionStart = txtSecound.Text.Length;
  566. }
  567. else
  568. {
  569. SetText_Secound(newSecound.ToString());
  570. SetSecound(newSecound);
  571. }
  572. }
  573. else
  574. {
  575. SetSecound(0);
  576. SetText_Secound("0");
  577. }
  578. }
  579. }
  580. private void SetText_Secound(string newValue)
  581. {
  582. txtSecound.TextChanged -= txtSecound_Changed;
  583. txtSecound.Text = newValue;
  584. txtSecound.TextChanged += txtSecound_Changed;
  585. }
  586. private void SetSecound(int secound)
  587. {
  588. CanRaiseTxtChaned_Secound_AttachDP = false;
  589. this.Secound = secound;
  590. CanRaiseTxtChaned_Secound_AttachDP = true;
  591. }
  592. #endregion
  593.  
  594. #region IsYearVisible
  595. public bool IsYearVisible
  596. {
  597. get { return (bool)GetValue(IsYearVisibleProperty); }
  598. set { SetValue(IsYearVisibleProperty, value); }
  599. }
  600.  
  601. public static readonly DependencyProperty IsYearVisibleProperty =
  602. DependencyProperty.Register("IsYearVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsYearVisible));
  603.  
  604. private static void On_IsYearVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  605. {
  606. TimeSpanBox sender = d as TimeSpanBox;
  607. if (sender != null)
  608. {
  609. Grid innerGrid = (Grid)sender.Content;
  610. innerGrid.ColumnDefinitions[0].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  611. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  612. innerGrid.ColumnDefinitions[1].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  613. ? GridLength.Auto : new GridLength(0);
  614. if (innerGrid.ColumnDefinitions[0].Width == new GridLength(0))
  615. {
  616. sender.SetText_Year("0");
  617. sender.CanRaiseTxtChaned_Year_AttachDP = false;
  618. sender.Year = 0;
  619. sender.CanRaiseTxtChaned_Year_AttachDP = true;
  620. }
  621. }
  622. }
  623. #endregion
  624. #region IsMonthVisible
  625. public bool IsMonthVisible
  626. {
  627. get { return (bool)GetValue(IsMonthVisibleProperty); }
  628. set { SetValue(IsMonthVisibleProperty, value); }
  629. }
  630.  
  631. public static readonly DependencyProperty IsMonthVisibleProperty =
  632. DependencyProperty.Register("IsMonthVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsMonthVisible));
  633.  
  634. private static void On_IsMonthVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  635. {
  636. TimeSpanBox sender = d as TimeSpanBox;
  637. if (sender != null)
  638. {
  639. Grid innerGrid = (Grid)sender.Content;
  640. innerGrid.ColumnDefinitions[2].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  641. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  642. innerGrid.ColumnDefinitions[3].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  643. ? GridLength.Auto : new GridLength(0);
  644. }
  645. }
  646. #endregion
  647. #region IsDayVisible
  648. public bool IsDayVisible
  649. {
  650. get { return (bool)GetValue(IsDayVisibleProperty); }
  651. set { SetValue(IsDayVisibleProperty, value); }
  652. }
  653.  
  654. public static readonly DependencyProperty IsDayVisibleProperty =
  655. DependencyProperty.Register("IsDayVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsDayVisible));
  656.  
  657. private static void On_IsDayVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  658. {
  659. TimeSpanBox sender = d as TimeSpanBox;
  660. if (sender != null)
  661. {
  662. Grid innerGrid = (Grid)sender.Content;
  663. innerGrid.ColumnDefinitions[4].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  664. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  665. innerGrid.ColumnDefinitions[5].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  666. ? GridLength.Auto : new GridLength(0);
  667. }
  668. }
  669. #endregion
  670. #region IsHourVisible
  671. public bool IsHourVisible
  672. {
  673. get { return (bool)GetValue(IsHourVisibleProperty); }
  674. set { SetValue(IsHourVisibleProperty, value); }
  675. }
  676.  
  677. public static readonly DependencyProperty IsHourVisibleProperty =
  678. DependencyProperty.Register("IsHourVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsHourVisible));
  679.  
  680. private static void On_IsHourVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  681. {
  682. TimeSpanBox sender = d as TimeSpanBox;
  683. if (sender != null)
  684. {
  685. Grid innerGrid = (Grid)sender.Content;
  686. innerGrid.ColumnDefinitions[6].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  687. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  688. innerGrid.ColumnDefinitions[7].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  689. ? GridLength.Auto : new GridLength(0);
  690. }
  691. }
  692. #endregion
  693. #region IsMinuteVisible
  694. public bool IsMinuteVisible
  695. {
  696. get { return (bool)GetValue(IsMinuteVisibleProperty); }
  697. set { SetValue(IsMinuteVisibleProperty, value); }
  698. }
  699.  
  700. public static readonly DependencyProperty IsMinuteVisibleProperty =
  701. DependencyProperty.Register("IsMinuteVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsMinuteVisible));
  702.  
  703. private static void On_IsMinuteVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  704. {
  705. TimeSpanBox sender = d as TimeSpanBox;
  706. if (sender != null)
  707. {
  708. Grid innerGrid = (Grid)sender.Content;
  709. innerGrid.ColumnDefinitions[8].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  710. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  711. innerGrid.ColumnDefinitions[9].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  712. ? GridLength.Auto : new GridLength(0);
  713. }
  714. }
  715. #endregion
  716. #region IsSecoundVisible
  717. public bool IsSecoundVisible
  718. {
  719. get { return (bool)GetValue(IsSecoundVisibleProperty); }
  720. set { SetValue(IsSecoundVisibleProperty, value); }
  721. }
  722.  
  723. public static readonly DependencyProperty IsSecoundVisibleProperty =
  724. DependencyProperty.Register("IsSecoundVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsSecoundVisible));
  725.  
  726. private static void On_IsSecoundVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
  727. {
  728. TimeSpanBox sender = d as TimeSpanBox;
  729. if (sender != null)
  730. {
  731. Grid innerGrid = (Grid)sender.Content;
  732. innerGrid.ColumnDefinitions[10].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  733. ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
  734. innerGrid.ColumnDefinitions[11].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
  735. ? GridLength.Auto : new GridLength(0);
  736. }
  737. }
  738. #endregion
  739.  
  740. #region IsReadOnly
  741. public bool IsReadOnly
  742. {
  743. get { return (bool)GetValue(IsReadOnlyProperty); }
  744. set { SetValue(IsReadOnlyProperty, value); }
  745. }
  746. public static readonly DependencyProperty IsReadOnlyProperty =
  747. DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(false, OnIsReadOnly_Changed));
  748.  
  749. private static void OnIsReadOnly_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  750. {
  751. TimeSpanBox sender = d as TimeSpanBox;
  752. if (sender != null)
  753. {
  754. bool isreadOnly = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true;
  755. sender.txtYear.IsReadOnly = isreadOnly;
  756. sender.txtYear.IsReadOnly = isreadOnly;
  757. sender.txtYear.IsReadOnly = isreadOnly;
  758. sender.txtYear.IsReadOnly = isreadOnly;
  759. sender.txtYear.IsReadOnly = isreadOnly;
  760. sender.txtYear.IsReadOnly = isreadOnly;
  761. }
  762. }
  763. #endregion
  764. #region Year
  765. public int Year
  766. {
  767. get { return (int)GetValue(YearProperty); }
  768. set { SetValue(YearProperty, value); }
  769. }
  770. public static readonly DependencyProperty YearProperty =
  771. DependencyProperty.Register("Year", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Year_Changed));
  772.  
  773. private static void On_Year_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  774. {
  775. TimeSpanBox selector = d as TimeSpanBox;
  776. if (selector != null && selector.CanRaiseTxtChaned_Year_AttachDP == true)
  777. {
  778. if (e.NewValue == null)
  779. selector.SetText_Year("");
  780. else if (e.NewValue.GetType().Equals(typeof(int)))
  781. {
  782. selector.SetText_Year(int.Parse(e.NewValue.ToString()).ToString());
  783. }
  784. else
  785. {
  786. selector.SetText_Year("0");
  787. }
  788. }
  789. }
  790. #endregion
  791. #region Month
  792. public int Month
  793. {
  794. get { return (int)GetValue(MonthProperty); }
  795. set { SetValue(MonthProperty, value); }
  796. }
  797. public static readonly DependencyProperty MonthProperty =
  798. DependencyProperty.Register("Month", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Month_Changed));
  799. private static void On_Month_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  800. {
  801. TimeSpanBox selector = d as TimeSpanBox;
  802. if (selector != null && selector.CanRaiseTxtChaned_Month_AttachDP == true)
  803. {
  804. if (e.NewValue == null)
  805. selector.SetText_Month("");
  806. else if (e.NewValue.GetType().Equals(typeof(int)))
  807. {
  808. selector.SetText_Month(int.Parse(e.NewValue.ToString()).ToString());
  809. }
  810. else
  811. {
  812. selector.SetText_Month("0");
  813. }
  814. }
  815. }
  816. #endregion
  817. #region Day
  818. public int Day
  819. {
  820. get { return (int)GetValue(DayProperty); }
  821. set { SetValue(DayProperty, value); }
  822. }
  823. public static readonly DependencyProperty DayProperty =
  824. DependencyProperty.Register("Day", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, ON_Day_Changed));
  825.  
  826. private static void ON_Day_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  827. {
  828. TimeSpanBox selector = d as TimeSpanBox;
  829. if (selector != null && selector.CanRaiseTxtChaned_Day_AttachDP == true)
  830. {
  831. if (e.NewValue == null)
  832. selector.SetText_Day("");
  833. else if (e.NewValue.GetType().Equals(typeof(int)))
  834. {
  835. selector.SetText_Day(int.Parse(e.NewValue.ToString()).ToString());
  836. }
  837. else
  838. {
  839. selector.SetText_Day("0");
  840. }
  841. }
  842. }
  843. #endregion
  844. #region Hour
  845. public int Hour
  846. {
  847. get { return (int)GetValue(HourProperty); }
  848. set { SetValue(HourProperty, value); }
  849. }
  850. public static readonly DependencyProperty HourProperty =
  851. DependencyProperty.Register("Hour", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Hour_CHanged));
  852. private static void On_Hour_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  853. {
  854. TimeSpanBox selector = d as TimeSpanBox;
  855. if (selector != null && selector.CanRaiseTxtChaned_Hour_AttachDP == true)
  856. {
  857. if (e.NewValue == null)
  858. selector.SetText_Hour("");
  859. else if (e.NewValue.GetType().Equals(typeof(int)))
  860. {
  861. selector.SetText_Hour(int.Parse(e.NewValue.ToString()).ToString());
  862. }
  863. else
  864. {
  865. selector.SetText_Hour("0");
  866. }
  867. }
  868. }
  869. #endregion
  870. #region Minutes
  871. public int Minutes
  872. {
  873. get { return (int)GetValue(MinutesProperty); }
  874. set { SetValue(MinutesProperty, value); }
  875. }
  876. public static readonly DependencyProperty MinutesProperty =
  877. DependencyProperty.Register("Minutes", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Minute_CHanged));
  878.  
  879. private static void On_Minute_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  880. {
  881. TimeSpanBox selector = d as TimeSpanBox;
  882. if (selector != null && selector.CanRaiseTxtChaned_Minute_AttachDP == true)
  883. {
  884. if (e.NewValue == null)
  885. selector.SetText_Minute("");
  886. else if (e.NewValue.GetType().Equals(typeof(int)))
  887. {
  888. selector.SetText_Minute(int.Parse(e.NewValue.ToString()).ToString());
  889. }
  890. else
  891. {
  892. selector.SetText_Minute("0");
  893. }
  894. }
  895. }
  896. #endregion
  897. #region Secound
  898. public int Secound
  899. {
  900. get { return (int)GetValue(SecoundProperty); }
  901. set { SetValue(SecoundProperty, value); }
  902. }
  903. public static readonly DependencyProperty SecoundProperty =
  904. DependencyProperty.Register("Secound", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Secound_Changed));
  905.  
  906. private static void On_Secound_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  907. {
  908. TimeSpanBox selector = d as TimeSpanBox;
  909. if (selector != null && selector.CanRaiseTxtChaned_Secound_AttachDP == true)
  910. {
  911. if (e.NewValue == null)
  912. selector.SetText_Secound("");
  913. else if (e.NewValue.GetType().Equals(typeof(int)))
  914. {
  915. selector.SetText_Secound(int.Parse(e.NewValue.ToString()).ToString());
  916. }
  917. else
  918. {
  919. selector.SetText_Secound("0");
  920. }
  921. }
  922. }
  923. #endregion
  924.  
  925. #region 文本
  926. public string YearText
  927. {
  928. get { return (string)GetValue(YearTextProperty); }
  929. set { SetValue(YearTextProperty, value); }
  930. }
  931. public static readonly DependencyProperty YearTextProperty =
  932. DependencyProperty.Register("YearText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  933.  
  934. public string MonthText
  935. {
  936. get { return (string)GetValue(MonthTextProperty); }
  937. set { SetValue(MonthTextProperty, value); }
  938. }
  939. public static readonly DependencyProperty MonthTextProperty =
  940. DependencyProperty.Register("MonthText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  941.  
  942. public string DayText
  943. {
  944. get { return (string)GetValue(DayTextProperty); }
  945. set { SetValue(DayTextProperty, value); }
  946. }
  947. public static readonly DependencyProperty DayTextProperty =
  948. DependencyProperty.Register("DayText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  949.  
  950. public string HourText
  951. {
  952. get { return (string)GetValue(HourTextProperty); }
  953. set { SetValue(HourTextProperty, value); }
  954. }
  955. public static readonly DependencyProperty HourTextProperty =
  956. DependencyProperty.Register("HourText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  957.  
  958. public string MinuteText
  959. {
  960. get { return (string)GetValue(MinuteTextProperty); }
  961. set { SetValue(MinuteTextProperty, value); }
  962. }
  963. public static readonly DependencyProperty MinuteTextProperty =
  964. DependencyProperty.Register("MinuteText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  965.  
  966. public string SecoundText
  967. {
  968. get { return (string)GetValue(SecoundTextProperty); }
  969. set { SetValue(SecoundTextProperty, value); }
  970. }
  971. public static readonly DependencyProperty SecoundTextProperty =
  972. DependencyProperty.Register("SecoundText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
  973. #endregion
  974.  
  975. #region UpDownBtnVisible
  976. public Visibility UpDownBtnVisible
  977. {
  978. get { return (Visibility)GetValue(UpDownBtnVisibleProperty); }
  979. set { SetValue(UpDownBtnVisibleProperty, value); }
  980. }
  981. public static readonly DependencyProperty UpDownBtnVisibleProperty =
  982. DependencyProperty.Register("UpDownBtnVisible", typeof(Visibility), typeof(TimeSpanBox), new PropertyMetadata(Visibility.Collapsed, OnUpDownBtnVisible_Changed));
  983.  
  984. private static void OnUpDownBtnVisible_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  985. {
  986. TimeSpanBox selector = d as TimeSpanBox;
  987. if (selector != null)
  988. {
  989. selector.gridShow.Visibility = e.NewValue != null && e.NewValue is Visibility && (Visibility)e.NewValue == Visibility.Visible
  990. ? Visibility.Visible
  991. : Visibility.Collapsed;
  992. }
  993. }
  994. #endregion
  995.  
  996. #region 标题颜色
  997. public Brush TitleBrush
  998. {
  999. get { return (Brush)GetValue(TitleBrushProperty); }
  1000. set { SetValue(TitleBrushProperty, value); }
  1001. }
  1002.  
  1003. // Using a DependencyProperty as the backing store for TitleBrush. This enables animation, styling, binding, etc...
  1004. public static readonly DependencyProperty TitleBrushProperty =
  1005. DependencyProperty.Register("TitleBrush", typeof(Brush), typeof(TimeSpanBox), new PropertyMetadata(new SolidColorBrush(Colors.Black), on_TitleBrush_CHanged));
  1006.  
  1007. private static void on_TitleBrush_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  1008. {
  1009. TimeSpanBox sender = d as TimeSpanBox;
  1010. if (sender != null && e.NewValue != null && e.NewValue is Brush)
  1011. {
  1012. Brush newBrush = ((Brush)e.NewValue);
  1013. sender.txtbYear.Foreground = newBrush;
  1014. sender.txtbMonth.Foreground = newBrush;
  1015. sender.txtbDay.Foreground = newBrush;
  1016. sender.txtbMinute.Foreground = newBrush;
  1017. sender.txtbHour.Foreground = newBrush;
  1018. sender.txtbSecound.Foreground = newBrush;
  1019. }
  1020. else if (e.NewValue != null || !(e.NewValue is Brush))
  1021. {
  1022. sender.txtbYear.Foreground = new SolidColorBrush(Colors.Black);
  1023. sender.txtbMonth.Foreground = new SolidColorBrush(Colors.Black);
  1024. sender.txtbDay.Foreground = new SolidColorBrush(Colors.Black);
  1025. sender.txtbMinute.Foreground = new SolidColorBrush(Colors.Black);
  1026. sender.txtbHour.Foreground = new SolidColorBrush(Colors.Black);
  1027. sender.txtbSecound.Foreground = new SolidColorBrush(Colors.Black);
  1028. }
  1029. }
  1030. #endregion
  1031.  
  1032. }
  1033. }

如何使用:

        xmlns:local="clr-namespace:TimeEditerDemo"
.... <!--不显示年,不现实月,不显示秒,显示按钮,天时分红字,-->
<local:TimeSpanBox x:Name="pick" Height="25" TitleBrush="Red"
IsYearVisible="False" IsMonthVisible="False" IsSecoundVisible="False" UpDownBtnVisible="Visible"/>
<TextBox x:Name="inputNum"/>
<Button Content="Set Year" Click="Button_Click"/>
<TextBlock Margin="0 10 0 0">
<Run Text="当前时间:"/>
<Run Text="{Binding Year,ElementName=pick}"/>
<Run Text="年"/>
<Run Text="{Binding Month,ElementName=pick}"/>
<Run Text="月"/>
<Run Text="{Binding Day,ElementName=pick}"/>
<Run Text="日"/>
<Run Text="{Binding Hour,ElementName=pick}"/>
<Run Text="时"/>
<Run Text="{Binding Minutes,ElementName=pick}"/>
<Run Text="分"/>
<Run Text="{Binding Secound,ElementName=pick}"/>
<Run Text="秒"/>
</TextBlock> <x:Code>
private void Button_Click(object sender, RoutedEventArgs e)
{
int tempValue = 0;
pick.Day = int.TryParse(this.inputNum.Text, out tempValue) ? tempValue : 0;
}
</x:Code>

上述控件待完善: 给 Year、Month、Day、Hour、Minite、Secound、负值的时候的CoerceValueCallback

缺少对应的Year_Change  Month_Change Day_Change Hour_CHange Minite_Change Secound_Chang 等事件

//本人懒的弄了,UI也没有任何优化

运行结果

Bug Fix 初始化时设置时分秒后显示值为0

原因: UserControl 种的Initial事件种如果包含的BInding是Relative,不能及时更新对应的绑定源,如下

<TextBox Grid.Column="0" BorderBrush="Transparent" BorderThickness="0" x:Name="txtYear" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"
Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TimeSpanBox},Path=YearText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

WPF时间长度自定义选择控件TimeSpanBox的更多相关文章

  1. SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework

    3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...

  2. 【C#】wpf自定义calendar日期选择控件的样式

    原文:[C#]wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 ...

  3. WPF范围选择控件(RangeSelector)

    原文:WPF范围选择控件(RangeSelector) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/art ...

  4. Android 自定义支持快速搜索筛选的选择控件(一)

    Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...

  5. Android自定义View(RollWeekView-炫酷的星期日期选择控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义Cus ...

  6. asp.net中的时间日期选择控件

    asp.net中的时间日期选择控件 Posted on 2008-07-17 17:37 飛雪飄寒 阅读(22922) 评论(6) 编辑 收藏     在系统中经常需要进行时间日期选择(比如查询时间范 ...

  7. WPF自定义分页控件,样式自定义,简单易用

    WPF自定义分页控件 做了许久伸手党,终于有机会贡献一波,搜索一下WPF分页控件,还是多,但是不太通用,主要就是样式问题,这个WPF很好解决,还有一个就是分页控件嘛,只关心几个数字的变动就行了,把页码 ...

  8. WPF开发随笔收录-自定义图标控件

    一.前言 1.在以前自学的过程中,软件需要使用到图标的时候,总是第一个想法是下载一个图片来充当图标使用,但实际得出来的效果会出现模糊的现象.后来网上学习了字体图标库的用法,可以在阿里云矢量图网站那里将 ...

  9. WPF 自定义Button控件及样式

    这次通过最近做的小例子说明一下自定义Button控件和样式. 实现的效果为:

随机推荐

  1. java后端开发学习路线

    思维导图(欢迎克隆):https://www.processon.com/mindmap/5f563cd31e08531762c4e32b 主要包括:编程基础.研发工具.应用框架.运维知识(主要学会配 ...

  2. 哀悼疫情,全站灰色如何实现,CSS滤镜一行代码实现

    庚子清明,以国家之名哀悼,以国家之名哀悼在新冠肺炎疫情中牺牲的烈士和逝世的同胞! 向抗疫英雄致敬! 今日打开各样的app,各大电商,爱奇艺都是灰色的 这里我也一直很好奇该功能,前端如何实现,了解过后发 ...

  3. 国际关注,Panda 交易所获悉美银监机构批准特许银行托管加密资产

    近期,Panda 交易所注意到,根据此前与Cointelegraph分享的一份声明,美国货币监理署(OCC)正在授予联邦特许银行托管加密货币的权限. 鉴于加密钱包与其他种类资产的托管要求不同,这一问题 ...

  4. Jmeter(1)下载和安装

    一.Jmeter工具安装 1.jmeter安装包下载地址:http://jmeter.apache.org/,下载Binaries包,使用jmeter需要先安装jdk 2.解压后打开/bin目录下的j ...

  5. Mybatis学习-日志与分页

    日志 为什么需要日志 如果一个数据库操作出现了异常,需要排错,那么日志就是最好的助手 Mybatis通过使用内置的日志工厂提供日志功能,有一下几种实现方式: SLF4J Apache Commons ...

  6. Hive通过Jdbc获取表的字段信息

    参考代码如下: /** * 按顺序返回字段 * desc table的返回结果形式如下: hive> describe ind01acoM; OK acq_ins_id_cd string cu ...

  7. 容器编排系统k8s之Ingress资源

    前文我们了解了k8s上的service资源的相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14161950.html:今天我们来了解下k8s上的In ...

  8. Redis5.0 主从模式和高可用 搭建和测试报告

    Redis 单机模式很简单,相关测试水文看这里 Redis5 压力测试结果反馈报告 必须的,今天接着写水文,写一写现在redis 支持的三种集群,主从模式,哨兵模式,Cluster模式,今天先搞主从模 ...

  9. Kubernetes应用管理器OpenKruise之CloneSet

    OpenKruise OpenKruise 是 Kubernetes 的一个标准扩展,它可以配合原生 Kubernetes 使用,并为管理应用容器.sidecar.镜像分发等方面提供更加强大和高效的能 ...

  10. 解决uiautomator截取不到手机App界面信息

    今天在使用uiautomatorviewer进行安卓app控件定位的时候,出现以下异常,(用的是真机测试Android版本是10,据说是Android 8以后sdk自带的uiautomator直接打开 ...