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

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. js- for in 循环 只有一个目的,遍历 对象,通过对象属性的个数 控制循环圈数

    for in 循环会返回 原型 以及原型链上面的属性,不会打印系统自带的属性 var obj ={  name:'suan',  sex :'male',  age:150,  height:185, ...

  2. react路由初探(2)

    对着官网的例子反正是没有搞出来,所以搜了一大堆,最终搞出来了,记录一下 import React from 'react'; // 首先我们需要导入一些组件... (这个是中文网示例,按这个做,报一大 ...

  3. 【APIO2018】选圆圈(平面分块 | CDQ分治 | KDT)

    Description 给定平面上的 \(n\) 个圆,用三个参数 \((x, y, R)\) 表示圆心坐标和半径. 每次选取最大的一个尚未被删除的圆删除,并同时删除所有与其相切或相交的圆. 最后输出 ...

  4. Windows的API功能查询

    在逆向分析时,一些Windows的API函数往往是我们的突破口.但这些函数很难记得一清二楚,以下是我的查找办法,做个小结. 官网 https://docs.microsoft.com/en-us/wi ...

  5. 精尽Spring MVC源码分析 - 调式环境搭建

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  6. 字节跳动内部微服务架构-Docker实战学习笔记分享 真香

    前言 基于 Spring Cloud 的微服务设计和开发,已经越来越多地得到了更多企业的推广和应用,而 Spring Cloud 社区也在不断的迅速发展壮大之中,近几年时间,Spring Cloud ...

  7. IDEA中flink程序报错找不到类

    Idea中运行flink程序,报错找不到类,其中pom文件中一项依赖为: <dependency> <groupId>org.apache.flink</groupId& ...

  8. node目录

    1 [了解nodejs] 1.1 [node简介] 1.2 [node的特点] 1.3 [如何安装] 1.4 [如何运行] 2 [es6--基本语法] 2.1 [变量的解构赋值] 2.2 [解构赋值] ...

  9. CSRF学习

    前提环境:网站存在CSRF漏洞(也就是过于相信访问请求,只判断了用户是否存在cookie,并未判断请求的发起者) CSRF攻击原理,用户A需要转账,用户A正常向银行网站发送请求登录,登录成功后银行网站 ...

  10. MATLAB绘图,绘双坐标轴,绘一图二轴等

    clc; clear all; close all; % %% 画极坐标系 % x = 0:.01 * pi:0.5 * pi; % y = cos(x) + sqrt(-1) * sin(x); % ...