0

I'm attempting to refactor some code in a MVVM architecture.
The Model has public values that are changed directly.

The UI listens for changes in these values.

Below is the event signaling code:

public string LoadFilename   { get { return _loadFilename;   } set { _loadFilename   = value; OnPropertyChanged(); } }
public string SaveFilename   { get { return _saveFilename;   } set { _saveFilename   = value; OnPropertyChanged(); } }
public string OneSafFilename { get { return _oneSafFilename; } set { _oneSafFilename = value; OnPropertyChanged(); } }

public bool IsSaveEnabled           { get { return _isSaveEnabled;           } set { _isSaveEnabled           = value; OnPropertyChanged(); } }
public bool IsLoadEnabled           { get { return _isLoadEnabled;           } set { _isLoadEnabled           = value; OnPropertyChanged(); } }
public bool IsLoadCheckpointEnabled { get { return _isLoadCheckpointEnabled; } set { _isLoadCheckpointEnabled = value; OnPropertyChanged(); } }
public bool IsCheckpointEnabled     { get { return _isCheckpointEnabled;     } set { _isCheckpointEnabled     = value; OnPropertyChanged(); } }
public bool IsScenariosEnabled      { get { return _isScenariosEnabled;      } set { _isScenariosEnabled      = value; OnPropertyChanged(); } }

Here is the OnPropertyChanged function:

    public event PropertyChangedEventHandler PropertyChanged;

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

This seems like a lot of boilerplate for something that should be natural in MVVM.
I'd like to make it more concise, but I'm not sure where to start.

With views listening to the above properties, what should the getters and setters look like?

H H
  • 263,252
  • 30
  • 330
  • 514
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • I completelly agree with @HenkHolterman you can move the INPC implementation into the base class. Here is a small example I've used before http://stackoverflow.com/questions/33801100/where-i-need-to-define-inotifypropertychanged-in-case-of-base-and-sub-classes/33805183#33805183 – Ilan Oct 05 '16 at 14:09
  • First off, don't forget about language features that reduce derp (`PropertyChanged?.Invoke(...)`) Secondly, there are lots of ways to improve this situation, from T4 template generation of boilerplate, using type descriptors, wrapping your POCOs in IDynamicMetaObjectProviders, etc. –  Oct 06 '16 at 16:32

3 Answers3

3

Implementing the INPC always remains the ugly part of WPF/XAML. With a good base class it could reduce to { get { return _loadFilename; } set { Set(ref _loadFilename, value); } } but that's about as compact as it will get. Resharper has support for (refactoring to) this.

Btw, your code is also missing the optimization guard if(value != _loadFilename) . So a BindableBase base class is definitely a good idea.

H H
  • 263,252
  • 30
  • 330
  • 514
2

You may want to look into something like Fody's PropertyChanged, which rewrites the IL at build time to inject the change notification code.

Richard Szalay
  • 83,269
  • 19
  • 178
  • 237
-1
private type m_name;
    public type name
    {
        get { return m_name; }
        set
        {
            m_name = value;
            if (PropertyChanged != null)
            { PropertyChanged(this, new PropertyChangedEventArgs("name")); }
        }
    }

I use the above code for property changes that require a listener. type is the type of the property and name is the name of the property (change 'type' and 'name' anywhere seen in the code)

For a great tutorial on MVVM that explains more about property changes and code snippets, check out Jerry Nixon on youtube: https://www.youtube.com/watch?v=cB7KdYPQw1k It's a little outdated but still very helpful!

Ag71191
  • 83
  • 1
  • 9
  • Using "name" in quotes is a big step backward form the original code. And this is longer too. The OnPropertyChange() method belongs to the recommended pattern. – H H Oct 05 '16 at 14:23