以下控件采用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

<UserControl x:Class="WPFApp.Controls.TimeSpanBox.TimeSpanBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFApp.Controls.TimeSpanBox"
BorderBrush="Gray" BorderThickness="1" mc:Ignorable="d" Focusable="False"
d:DesignHeight="25" d:DesignWidth="200">
<UserControl.Resources>
<ControlTemplate x:Key="UPBtnTemplate" TargetType="{x:Type RepeatButton}">
<Border BorderThickness="0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="1">
<GradientStop Color="#FFF9FAFB" Offset="0" />
<GradientStop Color="#FFC4CCD4" Offset="0.973" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding Button.Content}" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X=".5" Y=".3"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="DownBtnTemplate" TargetType="{x:Type RepeatButton}">
<Border BorderThickness="0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="1">
<GradientStop Color="#FFC4CCD4" Offset="0.973" />
<GradientStop Color="#FFF9FAFB" Offset="0" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding Button.Content}" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X=".5" Y=".3"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Resources>
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" BorderBrush="Transparent" BorderThickness="0" x:Name="txtYear" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="年" Grid.Column="1" VerticalAlignment="Center" x:Name="txtbYear"/>
<TextBox Grid.Column="2" BorderBrush="Transparent" BorderThickness="0" x:Name="txtMonth" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="月" Grid.Column="3" VerticalAlignment="Center" x:Name="txtbMonth"/>
<TextBox Grid.Column="4" BorderBrush="Transparent" BorderThickness="0" x:Name="txtDay" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="天" Grid.Column="5" VerticalAlignment="Center" x:Name="txtbDay"/>
<TextBox Grid.Column="6" BorderBrush="Transparent" BorderThickness="0" x:Name="txtHour" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="时" Grid.Column="7" VerticalAlignment="Center" x:Name="txtbHour"/>
<TextBox Grid.Column="8" BorderBrush="Transparent" BorderThickness="0" x:Name="txtMinute" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="分" Grid.Column="9" VerticalAlignment="Center" x:Name="txtbMinute"/>
<TextBox Grid.Column="10" BorderBrush="Transparent" BorderThickness="0" x:Name="txtSecound" VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False" TextAlignment="Right" Padding="0,0,1,0"/>
<TextBlock Text="秒" Grid.Column="11" VerticalAlignment="Center" x:Name="txtbSecound"/>
<UniformGrid Grid.Column="12" Rows="2" x:Name="gridShow" Margin="1,0,0,0">
<RepeatButton Padding="0" Width="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Focusable="False"
VerticalContentAlignment="Center" Template="{StaticResource UPBtnTemplate}" Command="{x:Static local:TimeSpanBox.IncreaseCommand}">
<Path Height="6" Width="12" Stretch="Fill" Opacity="1" Fill="#FF554646"
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"/>
</RepeatButton>
<RepeatButton Padding="0" Width="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Focusable="False"
VerticalContentAlignment="Center" Template="{StaticResource DownBtnTemplate}" Command="{x:Static local:TimeSpanBox.DecreaseCommand}">
<Path Height="6" Width="12" Stretch="Fill" Opacity="1" Fill="#FF554646"
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"/>
</RepeatButton>
</UniformGrid>
</Grid>
</UserControl>

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace WPFApp.Controls.TimeSpanBox
{
public partial class TimeSpanBox : UserControl
{
private TextBox previousFocus = null;
public TimeSpanBox()
{
InitializeComponent(); MouseButtonEventHandler PreviewMouseDown = (o1, e1) =>
{
TextBox textbox = o1 as TextBox;
if (textbox != null)
{
textbox.Focus();
e1.Handled = true;
}
};
txtYear.PreviewMouseDown += PreviewMouseDown;
txtMonth.PreviewMouseDown += PreviewMouseDown;
txtDay.PreviewMouseDown += PreviewMouseDown;
txtHour.PreviewMouseDown += PreviewMouseDown;
txtMinute.PreviewMouseDown += PreviewMouseDown;
txtSecound.PreviewMouseDown += PreviewMouseDown; RoutedEventHandler GotFocus = (o1, e1) =>
{
TextBox txt = o1 as TextBox;
if (txt != null)
{
txt.SelectAll();
txt.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFBFEDF1"));
txt.Foreground = new SolidColorBrush(Colors.Black);
txt.PreviewMouseDown -= new MouseButtonEventHandler(PreviewMouseDown);
}
previousFocus = txt;
};
txtYear.GotFocus += GotFocus;
txtMonth.GotFocus += GotFocus;
txtDay.GotFocus += GotFocus;
txtHour.GotFocus += GotFocus;
txtMinute.GotFocus += GotFocus;
txtSecound.GotFocus += GotFocus; RoutedEventHandler LostFocus = (o1, e1) =>
{
var textBox = o1 as TextBox;
if (textBox != null)
{
textBox.Background = new SolidColorBrush(Colors.Transparent);
textBox.Foreground = new SolidColorBrush(Colors.Black);
textBox.PreviewMouseDown += new MouseButtonEventHandler(PreviewMouseDown);
}
};
txtYear.LostFocus += LostFocus;
txtMonth.LostFocus += LostFocus;
txtDay.LostFocus += LostFocus;
txtHour.LostFocus += LostFocus;
txtMinute.LostFocus += LostFocus;
txtSecound.LostFocus += LostFocus; KeyEventHandler KeyDowm = (o1, e1) =>
{
TextBox txt = o1 as TextBox;
if (e1.Key == Key.Enter || (e1.Key == Key.Right && txt.SelectionStart == txt.Text.Length))
{
FocusNextText(txt);
}
else if (((e1.Key == Key.Delete || e1.Key == Key.Back) && (txt.Text == "0" || string.IsNullOrEmpty(txt.Text))) ||
(txt.SelectionStart == 0 && e1.Key == Key.Left)
)
{
e1.Handled = true;
if (!(txt.SelectionStart == 0 && e1.Key == Key.Left))
txt.Text = "0";
FocusPreviousText(txt);
}
}; txtYear.PreviewKeyDown += KeyDowm;
txtMonth.PreviewKeyDown += KeyDowm;
txtDay.PreviewKeyDown += KeyDowm;
txtHour.PreviewKeyDown += KeyDowm;
txtMinute.PreviewKeyDown += KeyDowm;
txtSecound.PreviewKeyDown += KeyDowm; txtYear.TextChanged += TextYear_Changed;
txtMonth.TextChanged += txtMonth_Changed;
txtDay.TextChanged += txtDay_Changed;
txtHour.TextChanged += txtHour_Changed;
txtMinute.TextChanged += txtMinute_Changed;
txtSecound.TextChanged += txtSecound_Changed; txtbYear.MouseLeftButtonDown += (o1, e1) => { txtYear.Focus(); txtYear.SelectAll(); };
txtbMonth.MouseLeftButtonDown += (o1, e1) => { txtMonth.Focus(); txtMonth.SelectAll(); };
txtbDay.MouseLeftButtonDown += (o1, e1) => { txtDay.Focus(); txtDay.SelectAll(); };
txtbHour.MouseLeftButtonDown += (o1, e1) => { txtHour.Focus(); txtHour.SelectAll(); };
txtbMinute.MouseLeftButtonDown += (o1, e1) => { txtMinute.Focus(); txtMinute.SelectAll(); };
txtbSecound.MouseLeftButtonDown += (o1, e1) => { txtSecound.Focus(); txtSecound.SelectAll(); }; this.SetTextBoxBindingText(this.txtYear, "YearText");
this.SetTextBoxBindingText(this.txtMonth, "MonthText");
this.SetTextBoxBindingText(this.txtDay, "DayText");
this.SetTextBoxBindingText(this.txtHour, "HourText");
this.SetTextBoxBindingText(this.txtMinute, "MinuteText");
this.SetTextBoxBindingText(this.txtSecound, "SecoundText");
}
private void SetTextBoxBindingText(TextBox targetTxt,string bindingPath)
{
Binding binding = new Binding(bindingPath);
binding.Source = this;
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
targetTxt.SetBinding(TextBox.TextProperty, binding);
} #region 注册路由命令
#region 注册鼠标左键按下事件
static TimeSpanBox()
{
InitializeCommands();
//EventManager.RegisterClassHandler(typeof(TimeSpanBox),
// Mouse.MouseDownEvent, new MouseButtonEventHandler(TimeSpanBox.OnMouseLeftButtonDown), true);
}
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TimeSpanBox control = (TimeSpanBox)sender;
//如果某人点击控件的部分只,但是该控件没有聚焦,
//本空间需要获取焦点来处理正确处理键盘
if (!control.IsKeyboardFocusWithin)//获取一个值,该值指示键盘焦点是否处于元素边界内的任何位置(包括键盘焦点是否位于任何可视子元素的边界内)。
{
e.Handled = control.Focus() || e.Handled;
}
}
#endregion private static RoutedCommand m_IncreaseCommand;
private static RoutedCommand m_DecreaseCommand;
public static RoutedCommand IncreaseCommand
{
get
{
return m_IncreaseCommand;
}
}
public static RoutedCommand DecreaseCommand
{
get
{
return m_DecreaseCommand;
}
}
private static void InitializeCommands()
{
m_IncreaseCommand = new RoutedCommand("IncreaseCommand", typeof(TimeSpanBox));
CommandManager.RegisterClassCommandBinding(typeof(TimeSpanBox), new CommandBinding(m_IncreaseCommand, OnIncreaseCommand));
CommandManager.RegisterClassInputBinding(typeof(TimeSpanBox), new InputBinding(m_IncreaseCommand, new KeyGesture(Key.Up))); m_DecreaseCommand = new RoutedCommand("DecreaseCommand", typeof(TimeSpanBox));
CommandManager.RegisterClassCommandBinding(typeof(TimeSpanBox), new CommandBinding(m_DecreaseCommand, OnDecreaseCommand));
CommandManager.RegisterClassInputBinding(typeof(TimeSpanBox), new InputBinding(m_DecreaseCommand, new KeyGesture(Key.Down)));
} private static void OnDecreaseCommand(object sender, ExecutedRoutedEventArgs e)
{
TimeSpanBox control = sender as TimeSpanBox;
if (control != null && control.previousFocus != null)
{
if (control.previousFocus == control.txtYear)
{
control.Year = Math.Max(0, control.Year - 1);
control.txtYear.SelectAll();
}
else if (control.previousFocus == control.txtMonth)
{
control.Month = Math.Max(0, control.Month - 1);
control.txtMonth.SelectAll();
}
else if (control.previousFocus == control.txtDay)
{
control.Day = Math.Max(0, control.Day - 1);
control.txtDay.SelectAll();
}
else if (control.previousFocus == control.txtHour)
{
control.Hour = Math.Max(0, control.Hour - 1);
control.txtHour.SelectAll();
}
else if (control.previousFocus == control.txtMinute)
{
control.Minutes = Math.Max(0, control.Minutes - 1);
control.txtMinute.SelectAll();
}
else if (control.previousFocus == control.txtSecound)
{
control.Secound = Math.Max(0, control.Secound - 1);
control.txtSecound.SelectAll();
}
}
} private static void OnIncreaseCommand(object sender, ExecutedRoutedEventArgs e)
{
TimeSpanBox control = sender as TimeSpanBox;
if (control != null)
{
if (control.previousFocus == control.txtYear)
{
control.Year = Math.Min(99, control.Year + 1);
control.txtYear.SelectAll();
}
else if (control.previousFocus == control.txtMonth)
{
control.Month = Math.Min(11, control.Month + 1);
control.txtMonth.SelectAll();
}
else if (control.previousFocus == control.txtDay)
{
control.Day = Math.Min(30, control.Day + 1);
control.txtDay.SelectAll();
}
else if (control.previousFocus == control.txtHour)
{
control.Hour = Math.Min(23, control.Hour + 1);
control.txtHour.SelectAll();
}
else if (control.previousFocus == control.txtMinute)
{
control.Minutes = Math.Min(59, control.Minutes + 1);
control.txtMinute.SelectAll();
}
else if (control.previousFocus == control.txtSecound)
{
control.Secound = Math.Min(59, control.Secound + 1);
control.txtSecound.SelectAll();
}
}
}
#endregion #region 跳转到上个文本框
private void FocusNextText(TextBox currTxt)
{
TextBox[] textboxArray = new TextBox[] { txtYear, txtMonth, txtDay, txtHour, txtMinute, txtSecound };
bool[] isVisibleArray = new bool[] { IsYearVisible, IsMonthVisible, IsDayVisible, IsHourVisible, IsMinuteVisible, IsSecoundVisible }; int index = Array.IndexOf(textboxArray, currTxt);
if (index != -1)
{
var findTxt = textboxArray.Skip(index + 1).FirstOrDefault(txt => isVisibleArray[Array.IndexOf(textboxArray, txt)]);
if (findTxt != null)
{
findTxt.Focus();
}
}
}
#endregion
#region 跳转到下个文本框
private void FocusPreviousText(TextBox currTxt)
{
TextBox[] textboxArray = new TextBox[] { txtYear, txtMonth, txtDay, txtHour, txtMinute, txtSecound };
bool[] isVisibleArray = new bool[] { IsYearVisible, IsMonthVisible, IsDayVisible, IsHourVisible, IsMinuteVisible, IsSecoundVisible };
int index = Array.IndexOf(textboxArray, currTxt);
if (index != -1)
{
var findTxt = textboxArray.Take(index).Reverse().FirstOrDefault(txt => isVisibleArray[Array.IndexOf(textboxArray, txt)]);
if (findTxt != null)
{
findTxt.Focus();
}
}
}
#endregion #region 年份改变
private bool CanRaiseTxtChaned_Year_AttachDP = true;
private void TextYear_Changed(object sender, TextChangedEventArgs e)
{
string year = txtYear.Text;
if (string.IsNullOrEmpty(year))
{
SetYear(0);
if (txtYear.IsFocused == true)
txtYear.SelectAll();
}
else
{
int newYear = 0;
bool result = int.TryParse(year, out newYear);
if (result == true && newYear >= 0 && this.Year != newYear)
{
if (newYear > 99)
{
SetText_Year("99");
SetYear(99);
txtMonth.Focus();
}
else
{
SetText_Year(newYear.ToString());
SetYear(newYear);
}
if (txtYear.Text.Length == 2)
FocusNextText(txtYear);
}
else
{
SetYear(0);
SetText_Year("0");
}
}
}
private void SetText_Year(string newValue)
{
txtYear.TextChanged -= TextYear_Changed;
txtYear.Text = newValue;
txtYear.TextChanged += TextYear_Changed;
}
private void SetYear(int year)
{
CanRaiseTxtChaned_Year_AttachDP = false;
this.Year = year;
CanRaiseTxtChaned_Year_AttachDP = true;
}
#endregion
#region 月份改变
private bool CanRaiseTxtChaned_Month_AttachDP = true;
private void txtMonth_Changed(object sender, TextChangedEventArgs e)
{
string month = txtMonth.Text;
if (string.IsNullOrEmpty(month))
{
SetMonth(0);
if (txtMonth.IsFocused == true)
txtMonth.SelectAll();
}
else
{
int newMonth = 0;
bool result = int.TryParse(month, out newMonth);
if (result == true && newMonth >= 0 && this.Month != newMonth)
{
if (newMonth > 11)
{
SetText_Month("11");
SetMonth(11);
txtDay.Focus();
}
else
{
SetText_Month(newMonth.ToString());
SetMonth(newMonth);
}
if (txtMonth.Text.Length == 2)
FocusNextText(txtMonth);
}
else
{
SetMonth(0);
SetText_Month("0");
}
}
}
private void SetText_Month(string newValue)
{
txtMonth.TextChanged -= txtMonth_Changed;
txtMonth.Text = newValue;
txtMonth.TextChanged += txtMonth_Changed;
}
private void SetMonth(int month)
{
CanRaiseTxtChaned_Month_AttachDP = false;
this.Month = month;
CanRaiseTxtChaned_Month_AttachDP = true;
}
#endregion
#region 日改变
private bool CanRaiseTxtChaned_Day_AttachDP = true;
private void txtDay_Changed(object sender, TextChangedEventArgs e)
{
string day = txtDay.Text;
if (string.IsNullOrEmpty(day))
{
SetDay(0);
if (txtDay.IsFocused == true)
txtDay.SelectAll();
}
else
{
int newDay = 0;
bool result = int.TryParse(day, out newDay);
if (result == true && newDay >= 0 && this.Day != newDay)
{
if (newDay > 30)
{
SetText_Day("30");
SetDay(30);
txtHour.Focus();
}
else
{
SetText_Day(newDay.ToString());
SetDay(newDay);
}
if (txtDay.Text.Length == 2)
FocusNextText(txtDay);
}
else
{
SetDay(0);
SetText_Day("0");
}
}
}
private void SetText_Day(string newValue)
{
txtDay.TextChanged -= txtDay_Changed;
txtDay.Text = newValue;
txtDay.TextChanged += txtDay_Changed;
}
private void SetDay(int day)
{
CanRaiseTxtChaned_Day_AttachDP = false;
this.Day = day;
CanRaiseTxtChaned_Day_AttachDP = true;
}
#endregion
#region 时改变
private bool CanRaiseTxtChaned_Hour_AttachDP = true;
private void txtHour_Changed(object sender, TextChangedEventArgs e)
{
string hour = txtHour.Text;
if (string.IsNullOrEmpty(hour))
{
SetDay(0);
if (txtHour.IsFocused == true)
txtHour.SelectAll();
}
else
{
int newHour = 0;
bool result = int.TryParse(hour, out newHour);
if (result == true && newHour >= 0 && this.Hour != newHour)
{
if (newHour > 23)
{
SetText_Hour("23");
SetHour(23);
txtMinute.Focus();
}
else
{
SetText_Hour(newHour.ToString());
SetHour(newHour);
}
if (txtHour.Text.Length == 2)
FocusNextText(txtHour);
}
else
{
SetHour(0);
SetText_Hour("0");
}
}
}
private void SetText_Hour(string newValue)
{
txtHour.TextChanged -= txtHour_Changed;
txtHour.Text = newValue;
txtHour.TextChanged += txtHour_Changed;
}
private void SetHour(int hour)
{
CanRaiseTxtChaned_Hour_AttachDP = false;
this.Hour = hour;
CanRaiseTxtChaned_Hour_AttachDP = true;
}
#endregion
#region 分改变
private bool CanRaiseTxtChaned_Minute_AttachDP = true;
private void txtMinute_Changed(object sender, TextChangedEventArgs e)
{
string minute = txtMinute.Text;
if (string.IsNullOrEmpty(minute))
{
SetMinute(0);
if (txtMinute.IsFocused == true)
txtMinute.SelectAll();
}
else
{
int newMinute = 0;
bool result = int.TryParse(minute, out newMinute);
if (result == true && newMinute >= 0 && this.Minutes != newMinute)
{
if (newMinute > 59)
{
SetText_Minute("59");
SetMinute(59);
txtSecound.Focus();
}
else
{
SetText_Minute(newMinute.ToString());
SetMinute(newMinute);
}
if (txtMinute.Text.Length == 2)
FocusNextText(txtMinute);
}
else
{
SetMinute(0);
SetText_Minute("0");
}
}
}
private void SetText_Minute(string newValue)
{
txtMinute.TextChanged -= txtMinute_Changed;
txtMinute.Text = newValue;
txtMinute.TextChanged += txtMinute_Changed;
}
private void SetMinute(int Minute)
{
CanRaiseTxtChaned_Minute_AttachDP = false;
this.Minutes = Minute;
CanRaiseTxtChaned_Minute_AttachDP = true;
}
#endregion
#region 秒改变
private bool CanRaiseTxtChaned_Secound_AttachDP = true;
private void txtSecound_Changed(object sender, TextChangedEventArgs e)
{
string secound = txtSecound.Text;
if (string.IsNullOrEmpty(secound))
{
SetSecound(0);
if (txtSecound.IsFocused == true)
txtSecound.SelectAll();
}
else
{
int newSecound = 0;
bool result = int.TryParse(secound, out newSecound);
if (result == true && newSecound >= 0 && this.Secound != newSecound)
{
if (newSecound > 59)
{
SetText_Secound("59");
SetSecound(59);
txtSecound.SelectionStart = txtSecound.Text.Length;
}
else
{
SetText_Secound(newSecound.ToString());
SetSecound(newSecound);
}
}
else
{
SetSecound(0);
SetText_Secound("0");
}
}
}
private void SetText_Secound(string newValue)
{
txtSecound.TextChanged -= txtSecound_Changed;
txtSecound.Text = newValue;
txtSecound.TextChanged += txtSecound_Changed;
}
private void SetSecound(int secound)
{
CanRaiseTxtChaned_Secound_AttachDP = false;
this.Secound = secound;
CanRaiseTxtChaned_Secound_AttachDP = true;
}
#endregion #region IsYearVisible
public bool IsYearVisible
{
get { return (bool)GetValue(IsYearVisibleProperty); }
set { SetValue(IsYearVisibleProperty, value); }
} public static readonly DependencyProperty IsYearVisibleProperty =
DependencyProperty.Register("IsYearVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsYearVisible)); private static void On_IsYearVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[0].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[1].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
if (innerGrid.ColumnDefinitions[0].Width == new GridLength(0))
{
sender.SetText_Year("0");
sender.CanRaiseTxtChaned_Year_AttachDP = false;
sender.Year = 0;
sender.CanRaiseTxtChaned_Year_AttachDP = true;
}
}
}
#endregion
#region IsMonthVisible
public bool IsMonthVisible
{
get { return (bool)GetValue(IsMonthVisibleProperty); }
set { SetValue(IsMonthVisibleProperty, value); }
} public static readonly DependencyProperty IsMonthVisibleProperty =
DependencyProperty.Register("IsMonthVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsMonthVisible)); private static void On_IsMonthVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[2].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[3].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
}
}
#endregion
#region IsDayVisible
public bool IsDayVisible
{
get { return (bool)GetValue(IsDayVisibleProperty); }
set { SetValue(IsDayVisibleProperty, value); }
} public static readonly DependencyProperty IsDayVisibleProperty =
DependencyProperty.Register("IsDayVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsDayVisible)); private static void On_IsDayVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[4].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[5].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
}
}
#endregion
#region IsHourVisible
public bool IsHourVisible
{
get { return (bool)GetValue(IsHourVisibleProperty); }
set { SetValue(IsHourVisibleProperty, value); }
} public static readonly DependencyProperty IsHourVisibleProperty =
DependencyProperty.Register("IsHourVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsHourVisible)); private static void On_IsHourVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[6].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[7].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
}
}
#endregion
#region IsMinuteVisible
public bool IsMinuteVisible
{
get { return (bool)GetValue(IsMinuteVisibleProperty); }
set { SetValue(IsMinuteVisibleProperty, value); }
} public static readonly DependencyProperty IsMinuteVisibleProperty =
DependencyProperty.Register("IsMinuteVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsMinuteVisible)); private static void On_IsMinuteVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[8].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[9].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
}
}
#endregion
#region IsSecoundVisible
public bool IsSecoundVisible
{
get { return (bool)GetValue(IsSecoundVisibleProperty); }
set { SetValue(IsSecoundVisibleProperty, value); }
} public static readonly DependencyProperty IsSecoundVisibleProperty =
DependencyProperty.Register("IsSecoundVisible", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, On_IsSecoundVisible)); private static void On_IsSecoundVisible(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
Grid innerGrid = (Grid)sender.Content;
innerGrid.ColumnDefinitions[10].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? new GridLength(1, GridUnitType.Star) : new GridLength(0);
innerGrid.ColumnDefinitions[11].Width = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true
? GridLength.Auto : new GridLength(0);
}
}
#endregion #region IsReadOnly
public bool IsReadOnly
{
get { return (bool)GetValue(IsReadOnlyProperty); }
set { SetValue(IsReadOnlyProperty, value); }
}
public static readonly DependencyProperty IsReadOnlyProperty =
DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(false, OnIsReadOnly_Changed)); private static void OnIsReadOnly_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null)
{
bool isreadOnly = e.NewValue != null && e.NewValue is bool && (bool)e.NewValue == true;
sender.txtYear.IsReadOnly = isreadOnly;
sender.txtYear.IsReadOnly = isreadOnly;
sender.txtYear.IsReadOnly = isreadOnly;
sender.txtYear.IsReadOnly = isreadOnly;
sender.txtYear.IsReadOnly = isreadOnly;
sender.txtYear.IsReadOnly = isreadOnly;
}
}
#endregion
#region Year
public int Year
{
get { return (int)GetValue(YearProperty); }
set { SetValue(YearProperty, value); }
}
public static readonly DependencyProperty YearProperty =
DependencyProperty.Register("Year", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Year_Changed)); private static void On_Year_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Year_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Year("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Year(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Year("0");
}
}
}
#endregion
#region Month
public int Month
{
get { return (int)GetValue(MonthProperty); }
set { SetValue(MonthProperty, value); }
}
public static readonly DependencyProperty MonthProperty =
DependencyProperty.Register("Month", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Month_Changed));
private static void On_Month_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Month_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Month("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Month(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Month("0");
}
}
}
#endregion
#region Day
public int Day
{
get { return (int)GetValue(DayProperty); }
set { SetValue(DayProperty, value); }
}
public static readonly DependencyProperty DayProperty =
DependencyProperty.Register("Day", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, ON_Day_Changed)); private static void ON_Day_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Day_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Day("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Day(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Day("0");
}
}
}
#endregion
#region Hour
public int Hour
{
get { return (int)GetValue(HourProperty); }
set { SetValue(HourProperty, value); }
}
public static readonly DependencyProperty HourProperty =
DependencyProperty.Register("Hour", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Hour_CHanged));
private static void On_Hour_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Hour_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Hour("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Hour(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Hour("0");
}
}
}
#endregion
#region Minutes
public int Minutes
{
get { return (int)GetValue(MinutesProperty); }
set { SetValue(MinutesProperty, value); }
}
public static readonly DependencyProperty MinutesProperty =
DependencyProperty.Register("Minutes", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Minute_CHanged)); private static void On_Minute_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Minute_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Minute("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Minute(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Minute("0");
}
}
}
#endregion
#region Secound
public int Secound
{
get { return (int)GetValue(SecoundProperty); }
set { SetValue(SecoundProperty, value); }
}
public static readonly DependencyProperty SecoundProperty =
DependencyProperty.Register("Secound", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(0, On_Secound_Changed)); private static void On_Secound_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null && selector.CanRaiseTxtChaned_Secound_AttachDP == true)
{
if (e.NewValue == null)
selector.SetText_Secound("");
else if (e.NewValue.GetType().Equals(typeof(int)))
{
selector.SetText_Secound(int.Parse(e.NewValue.ToString()).ToString());
}
else
{
selector.SetText_Secound("0");
}
}
}
#endregion #region 文本
public string YearText
{
get { return (string)GetValue(YearTextProperty); }
set { SetValue(YearTextProperty, value); }
}
public static readonly DependencyProperty YearTextProperty =
DependencyProperty.Register("YearText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0")); public string MonthText
{
get { return (string)GetValue(MonthTextProperty); }
set { SetValue(MonthTextProperty, value); }
}
public static readonly DependencyProperty MonthTextProperty =
DependencyProperty.Register("MonthText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0")); public string DayText
{
get { return (string)GetValue(DayTextProperty); }
set { SetValue(DayTextProperty, value); }
}
public static readonly DependencyProperty DayTextProperty =
DependencyProperty.Register("DayText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0")); public string HourText
{
get { return (string)GetValue(HourTextProperty); }
set { SetValue(HourTextProperty, value); }
}
public static readonly DependencyProperty HourTextProperty =
DependencyProperty.Register("HourText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0")); public string MinuteText
{
get { return (string)GetValue(MinuteTextProperty); }
set { SetValue(MinuteTextProperty, value); }
}
public static readonly DependencyProperty MinuteTextProperty =
DependencyProperty.Register("MinuteText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0")); public string SecoundText
{
get { return (string)GetValue(SecoundTextProperty); }
set { SetValue(SecoundTextProperty, value); }
}
public static readonly DependencyProperty SecoundTextProperty =
DependencyProperty.Register("SecoundText", typeof(string), typeof(TimeSpanBox), new PropertyMetadata("0"));
#endregion #region UpDownBtnVisible
public Visibility UpDownBtnVisible
{
get { return (Visibility)GetValue(UpDownBtnVisibleProperty); }
set { SetValue(UpDownBtnVisibleProperty, value); }
}
public static readonly DependencyProperty UpDownBtnVisibleProperty =
DependencyProperty.Register("UpDownBtnVisible", typeof(Visibility), typeof(TimeSpanBox), new PropertyMetadata(Visibility.Collapsed, OnUpDownBtnVisible_Changed)); private static void OnUpDownBtnVisible_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox selector = d as TimeSpanBox;
if (selector != null)
{
selector.gridShow.Visibility = e.NewValue != null && e.NewValue is Visibility && (Visibility)e.NewValue == Visibility.Visible
? Visibility.Visible
: Visibility.Collapsed;
}
}
#endregion #region 标题颜色
public Brush TitleBrush
{
get { return (Brush)GetValue(TitleBrushProperty); }
set { SetValue(TitleBrushProperty, value); }
} // Using a DependencyProperty as the backing store for TitleBrush. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleBrushProperty =
DependencyProperty.Register("TitleBrush", typeof(Brush), typeof(TimeSpanBox), new PropertyMetadata(new SolidColorBrush(Colors.Black), on_TitleBrush_CHanged)); private static void on_TitleBrush_CHanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TimeSpanBox sender = d as TimeSpanBox;
if (sender != null && e.NewValue != null && e.NewValue is Brush)
{
Brush newBrush = ((Brush)e.NewValue);
sender.txtbYear.Foreground = newBrush;
sender.txtbMonth.Foreground = newBrush;
sender.txtbDay.Foreground = newBrush;
sender.txtbMinute.Foreground = newBrush;
sender.txtbHour.Foreground = newBrush;
sender.txtbSecound.Foreground = newBrush;
}
else if (e.NewValue != null || !(e.NewValue is Brush))
{
sender.txtbYear.Foreground = new SolidColorBrush(Colors.Black);
sender.txtbMonth.Foreground = new SolidColorBrush(Colors.Black);
sender.txtbDay.Foreground = new SolidColorBrush(Colors.Black);
sender.txtbMinute.Foreground = new SolidColorBrush(Colors.Black);
sender.txtbHour.Foreground = new SolidColorBrush(Colors.Black);
sender.txtbSecound.Foreground = new SolidColorBrush(Colors.Black);
}
}
#endregion }
}

如何使用:

        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}"/>

最新文章

  1. ASP.net 实现禁止用户重复登录
  2. panel的展开,关闭的一种应用。
  3. c++中函数中变量内存分配以及返回指针、引用类型的思考
  4. php 队列
  5. 【计算几何】bzoj1043 [HAOI2008]下落的圆盘
  6. 原版本的jquery 开发过程中发现jquery好像更新了
  7. HDU 4022 Bombing(stl,map,multiset,iterater遍历)
  8. Oracle的trunc和dbms_random.value随机取n条数据
  9. HDU5071 - Chat(STL模拟)
  10. a标签使用
  11. load和get
  12. SharpMap在web上的应用
  13. 企业IT管理员IE11升级指南【10】—— 如何阻止IE11的安装
  14. MySQL 无法启动,出现 “发生系统错误 1067。”
  15. flex 布局 出滚动条的操作
  16. Unity关闭shader中的光照模型以及如何自定义光照模型
  17. SPOJ_LCS2
  18. 2、Redis的基础知识
  19. Java语句
  20. Lucene的数值索引以及范围查询

热门文章

  1. LeetCode初级算法之数组:48 旋转图像
  2. springboot使用mybatis拦截进行SQL分页
  3. linux 上安装部署python
  4. thinkphp thinkphp6 安装JWT
  5. svn工具包+安装教程+使用ip访问
  6. css 12-CSS3属性详解:动画详解
  7. [水题日常]Luogu1113 杂务
  8. Javascript JQuery select选择之Safari与Firefox
  9. Spark性能调优篇六之调节数据本地化等待时长
  10. SpringBoot从入门到精通教程(二)