When to use a WPF Dependency Property versus INotifyPropertyChanged

倖福魔咒の 提交于 2019-12-28 11:44:11

问题


Do folks have any guidance on when a simple .NET property that fires INotifyPropertyChanged.PropertyChanged is sufficient in a view model? Then when do you want to move up to a full blown dependency property? Or are the DPs intended primarily for views?


回答1:


There are a few approaches:

1. The dependency property

While you using the dependency property it makes the most sense in elements-classes that have a visual appearance (UIElements).

Pros:

  • WPF do the logic stuff for you
  • Some mechanism like animation use only dependency property
  • 'Fits' ViewModel style

Cons:

  • You need to derive form DependencyObject
  • A bit awkward for simple stuff

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. The System.ComponentModel.INotifyPropertyChanged

Usually, when creating a data object, you’ll use this approach. It is simple and neat solution for Data-like stuff.

Pros and Cons - complementary to 1. You need to to implement only one event (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.PropertyNameChanged

Rising an event for each property with specified name(f.e. NameChanged). Event must have this name and it is up to you to handle/rise them. Similar approach as 2.

4. Get the binding

Using the FrameworkElement.GetBindingExpression() you can get the BindingExpression object and call BindingExpression.UpdateTarget() to refresh.

First and second are the most likely depending what is your goal.

All in all, it is Visual vs Data.




回答2:


As far as I know, DependencyProperty is only required when you need

  1. PropertyValue inheritence
  2. you need to allow the property to be set in Style setters
  3. Use animation for the property

etc.

These features will not be available with normal properties.




回答3:


DependencyProperty is required if you want to allow a binding to be set on the property. Usually this is for custom UIElements you create. You want to allow people to be able to bind data to your UIElements.

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

To do this requires that MyProperty is a dependancy property




回答4:


The main problem I see with INotifyPropertyChanged is if you viewmodel is complex containing many nested types it appears that you have to bubble the PropertyChanged event up through the hierarchy.




回答5:


As the other answers have already said enough about when to create dependency property. i.e.

  1. PropertyValue inheritence
  2. you need to use binding on a property
  3. Use animation for the property

The one more perspective/question on this is "In a WPF application is makes sense to create dependency properties in a control cause they are likely to change during user interaction like Height,width, text,content, background etc but what about other classes like Behaviors Classes(Non UI classes). Do properties in those classes need to be a dependency property?"

I won't say for very absolute or emphasis on some set of rules here but you should create your properties as DP. As from design perspective if a property is DP it's always in default form of WPF to use/bind.i.e.

  1. As a DP is much more fast/natural in reflecting changes compare to a normal CLR property.
  2. A DP has validation mechanism to validate the value assigned and a default structure to revert the value.
  3. A DP has Coerce value callback to control the limits of property.
  4. A DP has meta data associated with it unlike CLR property.

In terms of practices I've seen people doing many mistakes in nested bindings and then raising changes these kind of faults doesn't happen with a DP cause of it's design and compatibility of raising change itself. So with a little extra syntax you put a flexibility/performance/ easeness to your application. So go for it wherever affordable.

Still can't say sure for ViewModel classes/other helper classes. will update the answer if found convincing reasons in future.

Just a post worth reading on this topic



来源:https://stackoverflow.com/questions/3551204/when-to-use-a-wpf-dependency-property-versus-inotifypropertychanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!