何时使用WPF依赖项属性与INotifyPropertyChanged

何时使用WPF依赖项属性与INotifyPropertyChanged,wpf,binding,dependency-properties,inotifypropertychanged,Wpf,Binding,Dependency Properties,Inotifypropertychanged,对于激发INotifyPropertyChanged.PropertyChanged的简单.NET属性在视图模型中何时足够,人们有什么指导吗?那么,您希望何时升级到完整的依赖属性?还是DPs主要用于视图?据我所知,DependencyProperty仅在需要时才需要 属性值继承 您需要允许在样式设置器中设置属性 对属性使用动画 等等 这些功能在正常特性中不可用 有几种方法: 1。依赖项属性 当您使用dependency属性时,它在具有可视外观的元素类(UIElements)中最有意义 优点:

对于激发
INotifyPropertyChanged.PropertyChanged
的简单.NET属性在视图模型中何时足够,人们有什么指导吗?那么,您希望何时升级到完整的依赖属性?还是DPs主要用于视图?

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

  • 属性值继承
  • 您需要允许在样式设置器中设置属性
  • 对属性使用动画
  • 等等


    这些功能在正常特性中不可用

    有几种方法:

    1。依赖项属性

    当您使用dependency属性时,它在具有可视外观的元素类(
    UIElement
    s)中最有意义

    优点:

    • WPF为你做逻辑的事情
    • 某些机制(如动画)仅使用依赖项属性
    • “适合”视图模型样式
    缺点:

    • 您需要派生表单
      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.InotifyProperty已更改

    通常,在创建数据对象时,您将使用这种方法。这是一个简单而整洁的数据解决方案,比如东西

    赞成和反对-补充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.物业名称已更改

    为具有指定名称(f.e.NameChanged)的每个属性引发事件。事件必须具有此名称,由您来处理/发起。与第2条类似的方法

    四,。把装订好

    使用
    FrameworkElement.GetBindingExpression()
    可以获得
    BindingExpression
    对象 并调用
    BindingExpression.UpdateTarget()
    进行刷新

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


    总而言之,它是可视的vs数据。如果要允许在属性上设置绑定,则需要依赖属性。通常,这是针对您创建的自定义
    UIElement
    s。您想让人们能够将数据绑定到您的
    UIElement
    s

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

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

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

    其他答案已经充分说明了何时创建依赖属性。i、 e

  • 属性值继承
  • 您需要对属性使用绑定
  • 对属性使用动画
  • 关于这一点的另一个观点/问题是“在WPF应用程序中,在控件中创建依赖项属性是有意义的,因为它们在用户交互过程中可能会发生变化,如高度、宽度、文本、内容、背景等,但其他类如行为类(非UI类)又如何呢。这些类中的属性是否需要是依赖项属性?“

    这里我不会说非常绝对或者强调一些规则,但是你应该创建你的属性作为DP。从设计的角度来看,如果属性是DP,那么使用/bind总是默认的WPF形式

  • 因为DP在反映变化方面比普通CLR属性快得多/自然得多
  • DP有验证机制来验证分配的值,并有默认结构来还原值
  • DP具有强制值回调以控制属性的限制
  • 与CLR属性不同,DP具有与其关联的元数据
  • 在实践方面,我看到人们在嵌套绑定中犯了很多错误,然后引发了更改。由于DP的设计和引发更改本身的兼容性,这种错误不会发生。因此,通过一点额外的语法,您可以为应用程序增加灵活性/性能/易用性。所以,只要你负担得起,就去吧

    仍然无法确定ViewModel类/其他帮助器类。如果将来发现令人信服的原因,将更新答案


    这是一个很好的答案,值得更多的投票!如果可以,我会投两次票。:-)这其实是正确的答案。如果希望属性成为绑定的目标,则只需要DependencyProperty。除此之外,如果需要,您还可以使用标准属性加上INotifyPropertyChanged。我很确定我在使用INotifyPropertyChanged时多次这样做,您的答案中是否有不清楚的“隐藏方面”?