2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>

  在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师。最为出色的是他维护了两个博客:2,000Things You Should Know About C#  和 2,000 Things You Should Know About WPF 。他以类似微博式的150字简短语言来每天更新一条WPF和C#重要又容易被遗忘的知识。Follow他的博客也有一段日子了,很希望能够分享给大家。

  本系列我不仅会翻译他的每一个tip,也会加入自己开发之中的看法和见解。本系列我希望自己也能和他一样坚持下来,每天的进步才能促成伟大。

  在这里郑重说明.该系列是基于Sean Sexton先生的英文博客, Sean Sexton拥有全部版权和撤销权利。

 

  前文:<1-7> , <8-14>,<15-21>22-27>, <28-33>,<34-39>,<40-44>,<45-50>

 

  [小九的学堂,致力于以平凡的语言描述不平凡的技术。如要转载,请注明来源:小九的学堂cnblogs.com/xfuture]


  #57 依赖属性值变化时的通知事件

  当一个依赖属性值改变的时候,实现它的类可以随时得知其改变。当该类注册该依赖属性的时候可以指定PropertyChangedCallback来获取其事件。

  

PropertyMetadata ageMetadata =

    new PropertyMetadata(

        18,     // Default value

        new PropertyChangedCallback(OnAgeChanged),   // ** call when property changes

        new CoerceValueCallback(OnAgeCoerceValue));

 

// Register the property

AgeProperty =

    DependencyProperty.Register(

        "Age",                 // Property's name

        typeof(int),           // Property's type

        typeof(Person),        // Defining class' type

        ageMetadata,           // Defines default value & callbacks  (optional)

        new ValidateValueCallback(OnAgeValidateValue));   // validation (optional)

  该类可以通过回调的函数才处理当值改变时候的逻辑。比如通过一个值的改变影响另一个值。

  

private static void OnAgeChanged

    (DependencyObject depObj, DependencyPropertyChangedEventArgs e)

{

    Person p = (Person)depObj;

    p.AARPCandidate = (int)e.NewValue > 60 ? true : false;

}

 

  #58 验证依赖属性

  注册依赖属性时,可以进行验证回调。当依赖属性被指定一个新值得时候,可以先通过验证函数验证,返回true or false来表示其是否有效。当注册这个依赖属性的时候可以指定其验证回调函数。

  

AgeProperty =

    DependencyProperty.Register(

        "Age",                 // Property's name

        typeof(int),           // Property's type

        typeof(Person),        // Defining class' type

        ageMetadata,           // Defines default value & changed/coercion callbacks  (optional)

        new ValidateValueCallback(OnAgeValidateValue));   // *** validation (optional)

  验证回调函数可以对新值进行验证

  

private static bool OnAgeValidateValue (object value)

{

    int age = (int) value;

 

    // Only allow reasonable ages

    return (age > 0) && (age < 120);

}

  如果值不能被接受,则抛出exception

  

Person p = new Person("Samuel", "Clemens");

p.Age = 40;     // ok

p.Age = 300;    // throws System.ArgumentException

  

 

  #59 强制改变依赖属性值

  人在做事的时候,都需要考虑一个底线,很多时候做了过分的事情你就期望有人提醒你,“嗨,这个事情你越线了!”。依赖属性就有一个特性,可以在你越线的时候把你拉回底线。那就是CoerceValueCallback。当你apple新的value的时候,它是最后一层安全系数。

  你可以在定义这个依赖属性的时候,定义CoerceValueCallback.

  

PropertyMetadata ageMetadata =

    new PropertyMetadata(

        18,     // Default value

        new PropertyChangedCallback(OnAgeChanged),

        new CoerceValueCallback(OnAgeCoerceValue));    // ** allow class to coerce value

 

// Register the property

AgeProperty =

    DependencyProperty.Register(

        "Age",                 // Property's name

        typeof(int),           // Property's type

        typeof(Person),        // Defining class' type

        ageMetadata,           // Defines default value & changed/coercion callbacks  (optional)

        new ValidateValueCallback(OnAgeValidateValue));   // validation (optional)

  你可以在delegate的OnAgeCoerceValue方法里来控制它的界限,并给予其新值。

  

private static object OnAgeCoerceValue

    (DependencyObject depObj, object baseValue)

{

    int coercedValue = (int)baseValue;

 

    if ((int)baseValue > 120)

        coercedValue = 120;

 

    if ((int)baseValue < 1)

        coercedValue = 1;

 

    return coercedValue;

}

 

  #60 Wpf中基于依赖属性特性实现的一个例子

  依赖属性有三种回调函数类可以来进行控制:

  1. PropertyChangedCallback 当获取一个新值得时候触发

  2. ValidateValueCallback 决定值是否有效

  3. CoerceValueCallback 强制更改为其他值

  

  DataGrid.FrozenColumnCount是一个三种逻辑都实现了的例子。

  1. PropertyChangedCallback. 渲染标题的时候,使之能正确显示。

  2. ValidateValueCallback 验证是否为负值。

  3. CoerceValueCallback 如果赋予的值大于其行数,则强制为最大值。

 

  #61 响应变化

  在WPF编程中对依赖属性除了使用PropertyChangedCallback事件来进行响应变化,还有其他方式。

  有两种方式可以做到:

  1. Data Binding

  2. Triggers

 

  #62 Triggers

  下面介绍Triggers。可以通过触发器Triggers来响应值变化时引起的蝴蝶效应。

  由于触发器只能针对离散值。所以下面的例子是简单的布尔值关联的触发器Trigger

  

<CheckBox Content="Check Me" HorizontalAlignment="Center">

    <CheckBox.Style>

        <Style TargetType="CheckBox">

            <Style.Triggers>

                <Trigger Property="IsChecked" Value="true">

                    <Setter Property="Foreground" Value="BlueViolet"/>

                </Trigger>

            </Style.Triggers>

        </Style>

    </CheckBox.Style>

</CheckBox>

  但该checkbox选中的时候,字体会被触发更改为BlueViolet.这边是trigger实现值变化时蝴蝶效应的方法。

  

  2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>

  而且Triggers是不需要在后台代码中写任何code的。只需要在xaml中就可以实现逻辑。

 

你可能感兴趣的:(WPF)