在WPF中,使用附加属性和Behavior都可以给对象附加一些功能。“附加”的好处是不会影响原对象,二者完全隔离,可以独自修改。
下面的示例是“令文本框只能输入数字”,如果要令输入框文本框只能输入数字,容易想到在TextChanged事件中处理。下面两种方式中都有方法ValidateChanged,作用就是限定位数字。
注意
使用Behavior,需要引用System.Windows.Interactivity命名空间。在XAML中使用时,必须另起行,用<i:Interaction.Behaviors>标签包括起来。
附加属性的Snippet是propa,附加属性就像 Grid.Row="1"这样可以直接写在对象标签内。
Behavior的实现方式
public class TextBoxValidateBehavior : Behavior<TextBox> { public static readonly DependencyProperty NumberOnlyProperty = DependencyProperty.Register("NumberOnly", typeof(bool), typeof(TextBoxValidateBehavior), new PropertyMetadata(false)); /// <summary> /// 是否只允许数字 /// </summary> public bool NumberOnly { get { return (bool)GetValue(NumberOnlyProperty); } set { SetValue(NumberOnlyProperty, value); } } /// <summary> /// 允许的最大数值(NumberOnyl设为False时无效) /// </summary> public int MaxNumberValue { get { return (int)GetValue(MaxNumberValueProperty); } set { SetValue(MaxNumberValueProperty, value); } } public static readonly DependencyProperty MaxNumberValueProperty = DependencyProperty.Register("MaxNumberValue", typeof(int), typeof(TextBoxValidateBehavior), new PropertyMetadata(Int32.MaxValue)); protected override void OnAttached() { base.OnAttached(); if (AssociatedObject != null) { AssociatedObject.TextChanged += ValidateChanged; } } private void ValidateChanged(object sender, TextChangedEventArgs e) { if (NumberOnly) { //屏蔽中文输入和非法字符粘贴输入 var textBox = sender as TextBox; if (textBox == null) return; var change = new TextChange[e.Changes.Count]; e.Changes.CopyTo(change, 0); var offset = change[0].Offset; if (change[0].AddedLength <= 0) return; int num; if (Int32.TryParse(textBox.Text, out num) && num < MaxNumberValue) return; textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength); textBox.Select(offset, 0); } } protected override void OnDetaching() { base.OnDetaching(); if (AssociatedObject != null) { AssociatedObject.TextChanged -= ValidateChanged; } } }
使用Behavior,需要继承自Behavior<T>对象,此处因为只对TextBox处理,所以T为TextBox。关键的两个重写方法OnAttached和OnDetaching,分别添加、移除事件处理函数。
<TextBox Width="200" Height="25"> <i:Interaction.Behaviors> <td:TextBoxValidateBehavior NumberOnly="True" MaxNumberValue="1000"/> </i:Interaction.Behaviors> </TextBox>
附加属性的实现方式
public class TextBoxValidateAction { public static bool GetNumberOnly(DependencyObject obj) { return (bool)obj.GetValue(NumberOnlyProperty); } public static void SetNumberOnly(DependencyObject obj, bool value) { obj.SetValue(NumberOnlyProperty, value); } public static readonly DependencyProperty NumberOnlyProperty = DependencyProperty.RegisterAttached("NumberOnly", typeof(bool), typeof(TextBoxValidateAction), new PropertyMetadata(false, OnNumberOnlyChanged)); private static void OnNumberOnlyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { var textbox = obj as TextBox; if (textbox == null) return; textbox.TextChanged += ValidateChanged; } private static void ValidateChanged(object sender, TextChangedEventArgs e) { var numberOnly = GetNumberOnly((DependencyObject)sender); if (numberOnly) { //屏蔽中文输入和非法字符粘贴输入 var textBox = sender as TextBox; if (textBox == null) return; var change = new TextChange[e.Changes.Count]; e.Changes.CopyTo(change, 0); var offset = change[0].Offset; if (change[0].AddedLength <= 0) return; int num; if (Int32.TryParse(textBox.Text, out num) && num < 1000) return; textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength); textBox.Select(offset, 0); } } }
使用附加属性,必须针对所有属性设置更新回调函数,附加属性的原理就是在更新回调函数中附加事件处理方法。
<TextBox Width="200" Height="25" td:TextBoxValidateAction.NumberOnly="True"/>
附加属性和Behavior
时间: 2024-11-07 19:09:00