• WPF Unleashed Chapter 3:Important New Concepts in WPF Dependency Properties (Support for Multiple Providers)


    声明: 本译文仅供学习讨论,禁止用于商业用途,否则后果自负

    Support for Multiple Providers
        
            WPF包含了很多强大的机制(指属性提供者,译者注),可以独立地设置DP的值。如果没有明确的机制去处理这些迥然不同的属性值提供者,那么系统会变得混乱,属性的值也会不能预测。从这些提供者的名字可以看出,dp的值会按照一定顺序设置 。  

            图3.5 展示WPF为dp赋值的5个步骤。DP内置的变更通知特性使得该过程可以自动完成。   
             
      
    Step 1: 确定基础值(Determine Base Value)   
            大多数属性提供这都会影响基础值。下面列出了8个提供者,按照优先级从高到低排列:   
      
    1. Local value                                               2. Style triggers   
    3. Template triggers                                         4. Style setters    
    5. Theme style triggers                                      6. Theme style setters   
    7. Property value inheritance                                8. Default value    
      
            您之前已经看到了一些属性值提供者,例如之前的属性值继承就是其中之一。Local Value可以用DependencyObject.SetValue进行赋值,但典型的赋值手段一般是在XAML或程序代码中使用属性进行赋值(因为dp实现了属性,例如之前的Button.IsDefault属性)。Default value是指dp注册时设置的默认值,它的优先级是最低的。其它的提供者我们将在第十章介绍。    
      
            提供者优先级的顺序解释了List3.4中StatusBar控件的FontSize和FontStyle不会受到属性值继承的影响原因。系统设置属于Theme Style setters,其优先级要高于Property value inheritance。所以您可以为StatusBar设置优先级更高的提供者,例如Local value。   
      
    Step 2: 求值(Evaluate)    
            如果step 1中的值是一个表达式(继承自System.Windows.Expression类的对象),WPF将会执行求职步骤,将表达式转换成具体的结果。在3.0版本的wpf中,只有在使用动态资源(dynamic resources)或数据绑定时,表达式才是有效的。以后的版本中会添加更多的表达式。   
      
    Step 3: 应用动画(Apply Animations)    
            如果元素的一个或者多个动画正在运行,这些动画会改变或完全替换相应的属性的值。所以,动画(第十三章)可以改变所有提供者设置的值--甚至是local value提供者。它对于WPF的新手来说是个学习过程中的绊脚石   
      
    Step 4: 强制(Coerce)    
            提供者设置完值以后,WPF得到了属性值的最终结果,并将它传递给CoerceValueCallback委托(如果在注册dp时注册了该委托)。这个委托会根据用户逻辑返回一个新值。例如WPF的ProgressBar就是用这个委托将dp的值约束在Minimun和Maximum之间   
      
    Step 5: 验证(Validate)    
            最后,第四步得到的值会传递给ValidateValueCallback。这个委托会返回一个布尔类型:通过验证返回true,否则返回false。如果返回false,系统会引发异常,终止整个过程   
      
    T I P

            如果您不知道dp属性当前的值从何而来,可以使用DependencyPropertyHelper类的静态方法GetValueSource。该方法会返回一个ValueSource结构,其中包含了一些相关信息:一个BaseValueSource的枚举,揭示基础值是的出处(步骤1);一系列布尔值:IsExpression,IsAnimated和IsCoerced。显示了2-4步的信息。   
            对List3.1或List3.4中的StatusBar的FontSize和FontStyle调用GetValueSource方法会返回DefaultStyle。说明这些值来自theme style setter提供者。并且不要在生产代码中使用这个方法!WPF的后续版本可能改变dp的source

      
        
    DIGGING DEEPER

    Clearing a Local Value
            之前的“变更通知”部分示范了使用程序代码在MouseEnter事件发生时改变Button的前景色,并在MouseLeave事件发生时将其变成黑色。这段代码的问题是,我们在MouseLeave中设置的黑色将作为是一个local value提供者的值而存在,而不是Button控件出示状态时使用theme style提供者的黑色。这样当主题(theme)改变后,新的主题会改变默认的前景色(或者比theme style优先级更高提供者改变了前景色)。由于local value提供者的优先级最高,这些变更将失效。   
            要想改变这种情况,我们可以使用DependencyObject.ClearValue来完成,假设Button的Name为b:   
    b.ClearValue(Button.ForegroundProperty);   
      
            Button的ForegroundProperty是静态的DP成员。调用了ClearValue方法后,local value就被简单地从基础值上删除了。  
            需要注意的是,“变更通知”的IsMouseOver触发器不存在上面的问题。触发器的状态只有活动(active)和停止(inactive)两种
    ,当触发器处于停止状态时,会被“属性值计算”所忽略  

      
          下一节介绍Dependency Property的最后一部分:Attached Properties
    如果您有WPF方面的问题,可以给我留言一起探讨,感谢大家浏览
  • 相关阅读:
    php中运算符的分类及注意事项
    ecshopv3.6安装
    phpstudy多站点配置教程
    织梦dedecms出现DedeCMS Error: (PHP 5.3 and above) Please set 'request_order' ini value to i解决办法
    thinkphp3.2批量删除功能
    怎么使用阿里图标库
    人人网,微博,QQ空间,朋友圈,常用API调用实现方法
    ueditor注意事项
    大图在小于自身的div中,水平居中
    thinkphp3.2 实现分页功能
  • 原文地址:https://www.cnblogs.com/stswordman/p/803455.html
Copyright © 2020-2023  润新知