代码之家  ›  专栏  ›  技术社区  ›  Keith Hill

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

  •  35
  • Keith Hill  · 技术社区  · 14 年前

    人们对何时触发简单的.NET属性有任何指导吗 INotifyPropertyChanged.PropertyChanged 视图模型中是否足够?那么,您希望何时向上移动到一个完整的依赖属性?或者DPS主要用于视图?

    5 回复  |  直到 9 年前
        1
  •  52
  •   Dave Clemmer manu    11 年前

    有几种方法:

    1。依赖属性

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

    赞成的意见:

    • WPF为你做逻辑方面的工作
    • 一些机制(如动画)只使用依赖属性
    • “适合”视图模型样式

    欺骗:

    • 你需要得到形式 DependencyObject
    • 对简单的东西有点尴尬

    Sample:

    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.inotifyPropertiesChanged

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

    优缺点-与1互补。您只需要实现一个事件(propertychanged)。

    Sample:

    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.名称已更改)的属性引发一个事件。事件必须有这个名称,由您来处理/提升它们。类似于2。

    4。得到装订

    使用 FrameworkElement.GetBindingExpression() 你可以得到 BindingExpression 对象 并打电话 BindingExpression.UpdateTarget() 刷新。

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

    总之,它是可视的vs数据。

        2
  •  14
  •   Dave Clemmer manu    11 年前

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

    1. 属性值继承
    2. 您需要允许在样式设置器中设置属性
    3. 为属性使用动画

    等。

    这些功能在正常属性下不可用。

        3
  •  3
  •   Dave Clemmer manu    11 年前

    DependencyProperty 如果要允许在属性上设置绑定,则是必需的。通常这是定制的 UIElement 你创造了。您希望允许人们能够将数据绑定到 铀元素 S.

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

    为此,需要MyProperty是Dependency属性

        4
  •  1
  •   Dave Clemmer manu    11 年前

    我看到的主要问题 INotifyPropertyChanged 如果ViewModel包含许多嵌套类型,则似乎必须在 PropertyChanged 通过层次结构向上的事件。

        5
  •  1
  •   Kylo Ren    9 年前

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

    1. 属性值继承
    2. 需要对属性使用绑定
    3. 为属性使用动画

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

    我不会说非常绝对或强调这里的一些规则集,但您应该将属性创建为dp。从设计的角度来看,如果一个属性是dp,那么它总是以wpf的默认形式使用/bind。

    1. 与正常的clr属性相比,dp在反映变化方面要快得多/自然得多。
    2. dp具有验证分配值的机制和恢复值的默认结构。
    3. DP具有强制值回调以控制属性限制。
    4. 与clr属性不同,dp具有与之关联的元数据。

    在实践中,我看到人们在嵌套绑定中犯了许多错误,然后引发更改,这种错误不会因为dp的设计和引发更改本身的兼容性而发生。因此,使用一些额外的语法,您可以为应用程序增加灵活性/性能/易用性。所以,只要能负担得起,就去买吧。

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

    Just a post worth reading on this topic