自己学着做了个自定义的控件,功能很简单,就是一个文本框,如果输入内容是数字,文本颜色为蓝
如果不是数字,文本颜色为红
- XML code
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" xmlns:local="clr-namespace:SLClient" > <!--The default style of MyCtrl--> <Style TargetType="local:MyCtrl"> <!--设置默认样式--> <Setter Property="Width" Value="100"/> <!--在该样式中,设置其模板内容--> <Setter Property="Template"> <Setter.Value> <!-- 定义模板 --> <ControlTemplate TargetType="local:MyCtrl"> <!--该模板中,应只有一个可视元素,在此用Grid--> <Grid> <!--定义可视状态组--> <vsm:VisualStateManager.VisualStateGroups> <!-- 数据有效性状态组 --> <VisualStateGroup x:Name="ValidStates"> <VisualState x:Name="Valid" /> <VisualState x:Name="UnValid" /> <!--定义状态转换动作--> <VisualStateGroup.Transitions> <!--当跳转至该状态时,进行转换--> <VisualTransition To="UnValid"> <!--时间轴--> <Storyboard> <!--动画设定.颜色渐变--> <ColorAnimation Storyboard.TargetName="textBox" Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)" To="Red"/> </Storyboard> </VisualTransition> <VisualTransition To="Valid"> <!--时间轴--> <Storyboard> <!--动画设定.颜色渐变--> <ColorAnimation Storyboard.TargetName="textBox" Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)" To="Blue"/> </Storyboard> </VisualTransition> </VisualStateGroup.Transitions> </VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <!--文本框--> <TextBox Name="textBox" Margin="0,0,0,0" Grid.Column="0" Grid.Row="0"></TextBox> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
- C# code
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SLClient { //定义该类的部件和状态 [TemplatePart(Name = "textBox", Type = typeof(TextBox))] [TemplateVisualState(Name = "Valid", GroupName = "ValidStates")] [TemplateVisualState(Name = "UnValid", GroupName = "ValidStates")] //我知道实现这样的功能,直接扩展TextBox更方便 //之所以这样做,只是想练习一下怎么做一个自定义控件罢了 //所以别告诉我应该扩展自TextBox,而不是 Control public class MyCtrl : Control { public MyCtrl() { //设置默认样式 this.DefaultStyleKey = typeof(MyCtrl); } //重载父类方法,当对该控件应用模板时该方法执行 public override void OnApplyTemplate() { base.OnApplyTemplate(); //获取模板中的部件 this.TextBox = this.GetTemplateChild("textBox") as TextBox; } private TextBox textBox; protected TextBox TextBox { get { return this.textBox; } set { if (this.textBox != null) {//取消事件注册 this.textBox.TextChanged -= new TextChangedEventHandler(textBox_TextChanged); } this.textBox = value; if (this.textBox != null) {//部件事件注册 this.textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged); } } } void textBox_TextChanged(object sender, TextChangedEventArgs e) { //数据有效性的判断 decimal num; bool valid = Decimal.TryParse(this.textBox.Text, out num); if (valid) { VisualStateManager.GoToState(this, "Valid", true); } else { VisualStateManager.GoToState(this, "UnValid", true); } } } }