附加属性和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"/>

附加属性和Behavior

时间: 2024-11-07 19:09:00

附加属性和Behavior的相关文章

WPF Interaction框架简介(一)——Behavior

在WPF 4.0中,引入了一个比较实用的库——Interactions,这个库主要是通过附加属性来对UI控件注入一些新的功能,除了内置了一系列比较好用的功能外,还提供了比较良好的扩展接口.本文这里简单的介绍一下Behavior这个扩展. 顾名思义,Behavior可以赋予控件新的行为能力,例如,我们可以通过MouseDragElementBehavior给控件附加上支持拖放的能力.使用方式如下: 添加Interactions库的引用.主要添加如下两个DLL:Microsoft.Expressio

wpf附加属性理解

WPF附加属性 http://www.cnblogs.com/tianyou/archive/2012/12/27/2835670.html WPF属性(二)附加属性 http://blog.csdn.net/iamsupercola/article/details/7069848 附加属性是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上,也就是把对象放入一个特定环境后对象才具有的属性就称为附加属性,附加属性的作用就是将属性与数据类型解耦,让数据类型的设计更加灵活. 这个解释的比较清

Yii2 behavior运用

1 class ReturnDataTypeBehaviors extends Behavior 2 { 3 4 public $type = 'json'; 5 public $pcOrMobile = 'pc'; // or mobile 6 7 //控制器执行之后事件 8 public function events() 9 { 10 return [Controller::EVENT_BEFORE_ACTION => 'beforeType']; 11 } 12 13 /** 14 *

(WPF)附加属性

<Window x:Class="DeepXAML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DeepXAML" xmlns:sys="

Unity中的行为树插件:Behavior Designer

外国技术人员的插件:http://www.opsive.com/assets/BehaviorDesigner 目前公司内部比较推崇的行为树插件就是这个,虽然有其他几个同类的竞品. 说一句题外话,优秀的插件总是外国人开发的,并且可以将插件开发做成一个小工作室或者个人的主要收入来源,但没看到国人有类似的作品出现. 行为树的概念出现已经很多年了,总的来说,就是使用各种经典的控制节点+行为节点进行组合,从而实现复杂的AI.目前在游戏中一般复杂的AI都可以看到行为树的身影,简单的AI可以使用状态机来实现

WPF QuickStart系列之附加属性(Attached Property)

这一篇博客是关于如何使用附加属性和创建自定义附加属性的. 1. 附加属性使用, WPF中对附加属性使用最多的莫过于对控件布局时设置控件的位置,例如在Canvas中有一个Rectangle, Ellipse, Button,我们需要设置它们的位置, <Canvas> <Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas

Behavior trees for AI: How they work

http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php by Chris Simpson on 07/17/14 09:35:00 pm       27 comments       The following blog post, unless otherwise noted, was written by a member of Gamasutra

[UWP]xaml中自定义附加属性使用方法的注意项

---恢复内容开始--- 随笔小记,欢迎指正 在UWP平台上做WVVM的时候,想针对ListBox的SelectionChanged事件定义一个自定义的命令,于是使用自定义附加属性的方式.可是最后自定义附加属性SelectionChangedCommand写好了,却不知道怎么在XAML中使用. 我的自定义属性如下: namespace SelectionChangedCommand.Services { public static class SelectionChangedBehavior {

WPF学习(三) - 依赖属性和附加属性

学习WPF时,我在看一本叫做“深入浅出WPF”的书.整整20页都在讲依赖性性和附加属性,反复看了几遍居然还是不懂,真是郁闷. 上一篇中WPF绑定的例子,其实已经用到了依赖属性. // 作为被绑定的目标类,必须从DependencyObject派生 // 这样定义的类才能满足SetBinding方法的第一个参数的类型要求 // 还要额外定义一个依赖属性,用来满足SetBinding方法的第二个参数要求 // 用DependencyObject派生方法GetValue和SetValue,控制属性的存