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

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

  #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实现值变化时蝴蝶效应的方法。


  

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

目录
相关文章
|
6月前
|
C# Windows
2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>
2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>
54 0
|
6月前
|
C# Windows
2000条你应知的WPF小姿势 基础篇<74-77 WPF 多窗口Tips>
2000条你应知的WPF小姿势 基础篇<74-77 WPF 多窗口Tips>
57 0
|
6月前
|
开发框架 .NET C#
2000条你应知的WPF小姿势 基础篇<63-68 Triggers和WPF类逻辑结构>
2000条你应知的WPF小姿势 基础篇<63-68 Triggers和WPF类逻辑结构>
30 0
|
6月前
|
C#
2000条你应知的WPF小姿势 基础篇<69-73 WPF Freeze机制和Template>
2000条你应知的WPF小姿势 基础篇<69-73 WPF Freeze机制和Template>
39 0
|
6月前
|
C#
2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
52 0
|
6月前
|
IDE C# 开发工具
2000条你应知的WPF小姿势 基础篇<40-44 启动关闭,Xaml,逻辑树>
2000条你应知的WPF小姿势 基础篇<40-44 启动关闭,Xaml,逻辑树>
31 0
|
6月前
|
存储 开发框架 .NET
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
22 0
|
6月前
|
存储 安全 程序员
2000条你应知的WPF小姿势 基础篇<34-39 Unhandled Exceptions和Resource>
2000条你应知的WPF小姿势 基础篇<34-39 Unhandled Exceptions和Resource>
16 0
2000条你应知的WPF小姿势 基础篇<34-39 Unhandled Exceptions和Resource>
|
6月前
|
C# C++ Windows
2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>
2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>
34 0
|
6月前
|
程序员 C# C++
2000条你应知的WPF小姿势 基础篇<22-27 WPF生命周期, 基础类等>
2000条你应知的WPF小姿势 基础篇<22-27 WPF生命周期, 基础类等>
26 0