何时使用WPF依赖属性与INotifyPropertyChanged

时间:2010-08-23 19:59:27

标签: wpf binding dependency-properties inotifypropertychanged

对于在视图模型中触发INotifyPropertyChanged.PropertyChanged的简单.NET属性何时足够,人们有什么指导吗?那么你什么时候想要升级到一个完整的依赖属性?或者DP主要用于观看?

5 个答案:

答案 0 :(得分:52)

有几种方法:

<强> 1。依赖属性

在使用依赖项属性时,它在具有可视外观(UIElement s)的元素类中最有意义。

优点:

  • WPF为你做逻辑工作
  • 某些机制(如动画仅使用依赖属性
  • '适合'ViewModel风格

缺点:

  • 您需要派生表单DependencyObject
  • 简单的东西有点尴尬

样品:

public static class StoryBoardHelper
{
    public static DependencyObject GetTarget(Timeline timeline)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        return timeline.GetValue(TargetProperty) as DependencyObject;
    }

    public static void SetTarget(Timeline timeline, DependencyObject value)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        timeline.SetValue(TargetProperty, value);
    }

    public static readonly DependencyProperty TargetProperty =
            DependencyProperty.RegisterAttached(
                    "Target",
                    typeof(DependencyObject),
                    typeof(Timeline),
                    new PropertyMetadata(null, OnTargetPropertyChanged));

    private static void OnTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Storyboard.SetTarget(d as Timeline, e.NewValue as DependencyObject);
    }
}

<强> 2。 System.ComponentModel.INotifyPropertyChanged

通常,在创建数据对象时,您将使用此方法。这是类似数据的东西的简单而简洁的解决方案。

优点和缺点 - 补充1.你需要只实现一个事件(PropertyChanged)。

示例:

public class Student : INotifyPropertyChanged 
{ 
   public event PropertyChangedEventHandler PropertyChanged; 
   public void OnPropertyChanged(PropertyChangedEventArgs e) 
   { 
       if (PropertyChanged != null) 
          PropertyChanged(this, e); 
   } 
}

private string name; 
public string Name; 
{ 
    get { return name; } 
    set { 
           name = value; 
           OnPropertyChanged(new PropertyChangedEventArgs("Name")); 
        } 
} 

3.PropertyName 的改

为具有指定名称的每个属性(f.e.NameChanged)上升事件。事件必须具有此名称,由您来处理/升级它们。与2相似的方法。

4。获得绑定

使用FrameworkElement.GetBindingExpression(),您可以获得BindingExpression个对象 并致电BindingExpression.UpdateTarget()进行刷新。

第一个和第二个最有可能取决于你的目标。

总而言之,它是Visual vs Data。

答案 1 :(得分:14)

据我所知,DependencyProperty仅在您需要时才需要

  1. PropertyValue inheritence
  2. 您需要允许在样式设置器
  3. 中设置属性
  4. 为属性使用动画
  5. 等。

    这些功能在普通属性中不可用。

答案 2 :(得分:4)

如果要允许在属性上设置绑定,则需要

DependencyProperty。通常这适用于您创建的自定义UIElement。您希望允许人们将数据绑定到您的UIElement

<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />

要做到这一点,要求MyProperty是一个依赖属性

答案 3 :(得分:1)

我在INotifyPropertyChanged看到的主要问题是,如果viewmodel是复杂的,包含许多嵌套类型,则表明您必须在层次结构中冒泡PropertyChanged事件。

答案 4 :(得分:1)

正如其他答案已经足够说明何时创建依赖属性。即。

  
      
  1. PropertyValue inheritence
  2.   
  3. 您需要在属性上使用绑定
  4.   
  5. 为属性使用动画
  6.   

关于这一点的另一个观点/问题是&#34;在WPF应用程序中,在控件中创建依赖项属性是有意义的,因为它们可能在用户交互期间发生变化,如高度,宽度,文本,内容,背景等但是其他类如行为类(非UI类)呢?这些类中的属性是否需要是依赖属性?&#34;

我绝对不会说绝对或强调某些规则,但你应该将你的属性创建为DP。从设计的角度来看,如果属性是DP,它总是以WPF的默认形式使用/ bind.i.e。

  
      
  1. 与正常的CLR属性相比,DP在反映变化方面更快/更自然。
  2.   
  3. DP具有验证机制以验证分配的值以及恢复值的默认结构。
  4.   
  5. DP具有Coerce值回调以控制属性的限制。
  6.   
  7. 与CLR属性不同,DP具有与之关联的元数据。
  8.   

就实践而言,我已经看到人们在嵌套绑定中犯了很多错误然后提出改变这些错误并不会因为它的设计和改变的兼容性而导致这种错误发生本身。因此,通过一些额外的语法,您可以为应用程序提供灵活性/性能/易用性。所以,只要负担得起,就去吧。

仍然无法确定ViewModel类/其他帮助程序类。如果在将来找到令人信服的理由,我们会更新答案。

Just a post worth reading on this topic