基于wpf平台实现的自定义控件
主要实现小时到分钟的切换,也接收tab切换/句点键切换
实现效果如下图:
xaml代码如下:
<UserControl x:Class="HibernateTest.TimeEdit"
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"
mc:Ignorable="d" FontWeight="Bold" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Height="Auto" Width="Auto" Name="ucontrol" IsEnabled="True" >
<UserControl.Resources>
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<!--<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>-->
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<!--<Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"
SnapsToDevicePixels="true">-->
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<!--</Microsoft_Windows_Themes:ListBoxChrome>-->
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Border BorderBrush="Black" BorderThickness="1" >
<WrapPanel>
<TextBox Height="Auto" Name="textBox1" Tag="1" Text="12" Width="Auto" HorizontalAlignment="Left"
GotFocus="tbox_GotFocus" LostFocus="tbox_LostFocus" PreviewMouseDown="tbox_PreviewMouseDown" KeyUp="tbox_KeyUp" KeyDown="tbox_KeyDown"
HorizontalContentAlignment="Center" Padding="0" BorderThickness="0" TextChanged="tbox_TextChanged" MouseWheel="tbox_MouseWheel" IsEnabled="True" TabIndex="1" />
<TextBox Width="Auto" Text =":" Height="Auto" HorizontalAlignment="Left" Name="tbox_1" VerticalContentAlignment="Center" Padding="0" IsEnabled="True" BorderThickness="0" />
<TextBox Height="Auto" Name="textBox2" Tag="2" Text="31" Width="Auto" HorizontalAlignment="Left"
GotFocus="tbox_GotFocus" LostFocus="tbox_LostFocus" PreviewMouseDown="tbox_PreviewMouseDown" KeyUp="tbox_KeyUp" KeyDown="tbox_KeyDown"
HorizontalContentAlignment="Center" TextChanged="tbox_TextChanged" MouseWheel="tbox_MouseWheel" TabIndex="2" IsEnabled="True" BorderThickness="0" />
</WrapPanel>
</Border>
</UserControl>
cs 代码:
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 HibernateTest
{
/// <summary>
/// UserControl1.xaml 的交互逻辑
/// </summary>
public partial class TimeEdit : UserControl
{
//背景颜色
public static DependencyProperty timeValProperty =
DependencyProperty.Register("TimeVal", typeof(string), typeof(TimeEdit), new PropertyMetadata("00:00", new PropertyChangedCallback(timeValChanged)));
public static readonly RoutedEvent onEdited = EventManager.RegisterRoutedEvent("onEdited", RoutingStrategy.Bubble, typeof(EventHandler<MyRoutedEventArgs>), typeof(TimeEdit));
//为事件添加处理程序的接口
public event EventHandler<MyRoutedEventArgs> OnEdited
{
add { base.AddHandler(onEdited, value); }
remove { base.RemoveHandler(onEdited, value); }
}
public string TimeVal
{
get { return (string)GetValue(timeValProperty); }
set { SetValue(timeValProperty, value); }
}
public TimeEdit()
{
InitializeComponent();
}
public static void timeValChanged(object sender, DependencyPropertyChangedEventArgs args)
{
TimeEdit bar = sender as TimeEdit;
if (args.Property.Equals(timeValProperty))
{
string newVal = args.NewValue.ToString();
if(newVal.Length == 5)
{
bar.textBox1.Text = newVal.Substring(0, 2);
bar.textBox2.Text = newVal.Substring(3, 2);
}
MyRoutedEventArgs e = new MyRoutedEventArgs(onEdited, bar);
bar.RaiseEvent(e);
}
}
private void tbox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
tb.Focus();
e.Handled = true;
}
}
private void tbox_GotFocus(object sender, RoutedEventArgs e)
{
if (sender != null)
{
TextBox tbx = sender as TextBox;
tbx.SelectAll();
tbx.PreviewMouseDown -= new MouseButtonEventHandler(tbox_PreviewMouseDown);
}
}
private void tbox_LostFocus(object sender, RoutedEventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
tb.PreviewMouseDown += new MouseButtonEventHandler(tbox_PreviewMouseDown);
}
if (!tb.Text.Contains('-'))
{
int i_value = getNum(tb); //单数 补零,如 9 -> 09
if (i_value >= 0)
{
tb.Text = formatNum(i_value); //补零
}
TimeVal = textBox1.Text + ":" + textBox2.Text;
}
}
//取出数字
private int getNum(TextBox tbox)
{
string val = tbox.Text.Trim();
int outNum = -1;
Int32.TryParse(val, out outNum);
return outNum;
}
//补零
private string formatNum(int i_num)
{
string i_str = " ";
if(i_num >= 0 &&(i_num <=9))
{
i_str = "0" + i_num.ToString();
}
else
{
i_str = i_num.ToString();
}
return i_str;
}
private void tbox_KeyUp(object sender, KeyEventArgs e)
{
TextBox tb = sender as TextBox;
string ss = tb.Text;
if (!ss.Contains('-'))
{
if (ss.Length > 2)
{
tb.Text = ss.Substring(ss.Length - 2, 2); //取后两位
tb.SelectAll();
tb.SelectionStart = 0;
if (tb.Name == "textBox1")
{
textBox2.Focus();
}
}
else if (ss.Length == 2)
{
tb.SelectAll();
tb.SelectionStart = 0;
if (tb.Name == "textBox1")
{
textBox2.Focus();
}
}
else if (ss.Length == 1)
{
tb.SelectAll();
tb.SelectionStart = 1;
}
}
if (textBox1.Text.Length == 2 && textBox2.Text.Length == 2)
{
TimeVal = textBox1.Text + ":" + textBox2.Text;
}
}
private void tbox_KeyDown(object sender, KeyEventArgs e)
{
TextBox txt = sender as TextBox;
//屏蔽非法按键
if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key == Key.Decimal || e.Key.ToString() == "Tab" || e.Key == Key.Subtract)
{
if ((txt.Text.Contains(".") && e.Key == Key.Decimal) || e.Key == Key.Subtract)
{
e.Handled = true;
return;
}
e.Handled = false;
}
else if (((e.Key >= Key.D0 && e.Key <= Key.D9) ) && e.KeyboardDevice.Modifiers != ModifierKeys.Shift)
{
if (txt.Text.Contains(".") || txt.Text.Contains("-"))
{
e.Handled = true;
return;
}
e.Handled = false;
}
else if (e.Key == Key.OemPeriod) //按下 句点 键
{
if (txt.Name == "textBox1") //小时 处 按下 句点键 时 切换到 分钟处,如果小时小于10 ,则前补零
{
if (!txt.Text.Contains('-'))
{
txt.Text = formatNum(getNum(txt));
}
textBox2.Focus();
e.Handled = true;
}
}
else if (e.Key == Key.OemMinus)
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
private void tbox_TextChanged(object sender, TextChangedEventArgs e)
{
//屏蔽中文输入和非法字符粘贴输入
TextBox textBox = sender as TextBox;
TextChange[] change = new TextChange[e.Changes.Count];
e.Changes.CopyTo(change, 0);
int offset = change[0].Offset;
if (change[0].AddedLength > 0)
{
double num = 0;
if(textBox.Text.Contains('-')) //不屏蔽 - 键盘
{
return;
}
else if (!Double.TryParse(textBox.Text, out num))
{
textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);
textBox.Select(offset, 0);
}
}
}
private void tbox_MouseWheel(object sender, MouseWheelEventArgs e)
{
TextBox tbox = sender as TextBox;
if (e.Delta > 0) //滚轮向上,减小
{
int i_num = getNum(tbox);
if (i_num > 0)
{
int i_new = i_num - 1;
tbox.Text = formatNum(i_new);
}
else if (i_num == 0) //滚动到零了,则更改为最大值
{
string tboxName = tbox.Name;
if (tboxName == "textBox1")
{
tbox.Text = "23";
}
else if (tboxName == "textBox2")
{
tbox.Text = "59";
}
}
}
else if (e.Delta < 0) //滚轮向下,增大
{
int i_num = getNum(tbox);
string tboxName = tbox.Name;
int i_new = i_num;
if(tboxName == "textBox1")
{
if (i_num <= 22 )
{
i_new = i_num + 1;
}
else if (i_num == 23)
{
i_new = 0; //到24,更改为0
}
else
{
i_new = i_num;
}
}
else if (tboxName == "textBox2")
{
if (i_num <= 58)
{
i_new = i_num + 1;
}
else if (i_num == 59)
{
i_new = 0; //到59,更改为0
}
else
{
i_new = i_num;
}
}
tbox.Text = formatNum(i_new);
}
TimeVal = textBox1.Text + ":" + textBox2.Text;
}
private void ucontrol_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
}
}
}