Re-implementing the same event invoker

2019-08-08 17:16发布

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?

3条回答
Luminary・发光体
2楼-- · 2019-08-08 17:54

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楼-- · 2019-08-08 18:05

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.

查看更多
叼着烟拽天下
4楼-- · 2019-08-08 18:15

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)

查看更多
登录 后发表回答