Re-implementing the same event invoker

北战南征 提交于 2020-01-15 10:14:17

问题


I'm writing a few classes and I want to make them all "data-binding compliant" (for WPF, or even the probably rarer WinForms) by implementing INotifyPropertyChanged.

The issue is the repeated code. I actually copy-paste the same method over and over again (I'm not joking).

protected void OnPropertyChanged([CallerMemberName] String propertyName = null)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

I had this issue for a while but today specifically it just keeps happening again and again, so I hope you could help me with a solution. I have almost a dozen classes that have this method and I really hate to repeat that piece of code.

I thought of creating a base class that will implement it (NotifyPropertyChangedObject for the name maybe) but that's probably a bad idea that will really limit my classes without multiple inheritance.
I also thought of an extension method but I would like to scope it as a protected method, so that won't work either.

What could be done to fix this issue?


回答1:


Having a base class is the method even MVVM Helper libraries do. There is no drawback to that.

Yes you can have only one base class for a c# class but have it implement multiple interfaces. For your case all you would have to do is say have a base class implement INPC and call it ViewModelBase

Now if currently you have Class X inherit from Class A, Just make A inherit from ViewModelBase.

You hence thus make your current base classes inherit from this new INPC providing class and you don't have any code duplication for INPC implementation in any of your derived classes

Update

In your special case where you are for whatever reason tied into already having another base class and with the restriction of not having say something like a public implementation of INPC passed to this object as a member variable,

You can try having a look at this:

Fody and in particular it's addon PropertyChanged - Addon

This will hopefully help you since it injects the INPC implementations itself, thus not requiring you to Copy Paste code and it also then allows you to derive from any custom base class(still need to specify INPC but thats just an interface here)




回答2:


I usually bind my view to a view model type object, i.e an object that contains all the data the view will need. This makes for a system that is easier to work on as the view must bind to only one object.

I will usually then have my business objects expose data to the view model and expose a single event to notify the view model that its state has changed, at which point the view model will call the relevant property specific notifications to the view. i.e You would only have to implement the above method once per view / view model.

Look into the MVVM model if you haven't already. The above is just one of myriad approaches and indeed is my interpretation which some may disagree with and which may or may not fit your particular scenario.




回答3:


To add to the answer by @viv. If you have already decided to use Fody+PropertyChanged I recommend avoiding a base class. Since PropertyChanged does all the INPC implementation for you there is really very little value in having a base class. In fact there is more pain than there is value. Just add the PropertyChanged.ImplementPropertyChanged attribute to your class and the rest will be done for you.

[ImplementPropertyChanged]
public class Person 
{
    public string Name { get; set; }
}

Regarding classes that you dont own and hence can be made to implement INPC. The best approach is create a duplicate class that represent a simplified version of each class you want to bind to. You can read and write the values when you load and finish with your view. Or if you only want to bind to certain properties just place these proprieties on your main view model.



来源:https://stackoverflow.com/questions/15636243/re-implementing-the-same-event-invoker

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