何时使用WPF依赖属性与INotifyPropertyChanged
对于在视图模型中引发INotifyPropertyChanged.PropertyChanged
的简单.NET属性是否足够,人们是否有任何指导? 那么你什么时候想要移动到一个完整的依赖项属性? 或者DP是主要用于观看?
有几种方法:
1.依赖属性
当你使用依赖属性时,它在具有可视外观的元素类( UIElement
s)中是最有意义的。
优点:
- WPF为你做逻辑的东西
- 像animation这样的一些机制只使用依赖属性
- '适合'ViewModel风格
缺点:
- 您需要派生forms
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
通常,在创build数据对象时,您将使用这种方法。 对于类似数据的东西来说,它是简单而整洁的解决scheme。
优点和缺点 – 对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已更改
为每个指定名称的财产(fe NameChanged)上升一个事件。 事件必须有这个名字,是由你来处理/崛起。 类似的方法2。
4.获取绑定
使用FrameworkElement.GetBindingExpression()
可以获得BindingExpression
对象,并调用BindingExpression.UpdateTarget()
来刷新。
第一和第二是最有可能取决于你的目标是什么。
总而言之,这是Visual vs Data。
据我所知, DependencyProperty
只在需要时才需要
- PropertyValueinheritance
- 您需要允许在样式设置器中设置属性
- 使用animation的财产
等等
这些function将不会与正常的属性。
如果要允许在属性上设置绑定,则需要DependencyProperty
。 通常这是为您创build的自定义UIElement
。 你想让人们能够将数据绑定到你的UIElement
。
<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />
要做到这一点,需要MyProperty是一个依赖属性
我用INotifyPropertyChanged
看到的主要问题是,如果viewmodel是复杂的,包含许多嵌套types,那么看起来您必须将PropertyChanged
事件向上冒泡通过层次结构。
正如其他答案已经足够说明何时创build依赖项属性。 即
- PropertyValueinheritance
- 你需要在一个属性上使用绑定
- 使用animation的财产
关于这一点的另一个观点/问题是“在WPF应用程序中,在控件中创build依赖项属性是有意义的,因为它们在用户交互期间可能会发生变化,如高度,宽度,文本,内容,背景等, 但其他类如行为类(非UI类)。在这些类中的属性需要是依赖属性?
我不会说绝对的或强调这里的一些规则,但你应该创build你的属性作为DP。 从devise的angular度来看,如果一个属性是DP,它总是以默认的WPFforms使用/ bind.ie
- 因为DP比正常的CLR属性更快速/更自然。
- 一个DP有validation机制来validation分配的值和一个默认结构来恢复该值。
- DP有Coerce值callback来控制属性的限制。
- 与CLR属性不同,DP具有与其关联的元数据。
就实践而言,我看到人们在嵌套绑定中犯了很多错误,然后提出了改变,这种错误不会发生在DP的原因是它的devise和提高变化的兼容性本身。 因此,使用一些额外的语法,您可以为应用程序提供灵活性/性能/易用性。 所以去任何地方负担得起的。
仍然不能确定的ViewModel类/其他辅助类。 如果今后find有说服力的理由,会更新答案。
只是一个值得阅读的话题