首页 > 代码库 > 附加属性和Behavior

附加属性和Behavior

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