3

I'm doing a very simple implementation of the MVC pattern in C# with a WPF interface.

I have a model that's keeping the state. I want to be able to notify the view form the model whenever anything about the state changes, so that the view can update itself accordingly.

What's the simplest best practice for doing this in WPF? I know there's such a thing as a PropertyChanged event, is that what I'm looking for or is that too specific for my situation?

Thanks!

Alexandr Kurilin
  • 7,685
  • 6
  • 48
  • 76
  • You might consider reading my articles here: http://reedcopsey.com/series/windows-forms-to-mvvm/ They go through how to think about this from a WPF perspective, including how and why to implement INotifyPropertyChanged. MVVM is just a WPF-friendly architectural pattern you can use as an alternative to MVC. – Reed Copsey Nov 24 '10 at 02:03

2 Answers2

3

Yes. Implement the interface INotifyPropertyChanged.

An example:

MainWindow.xaml

<Window x:Class="INotifyChangedDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Label Content="{Binding HitCount}"></Label>
    <Button Grid.Row="1" Click="Button_Click">
        Hit
    </Button>
</Grid>


MainWindow.xaml.cs

namespace INotifyChangedDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainViewModel _viewModel = new MainViewModel();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = _viewModel;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _viewModel.HitCount = _viewModel.HitCount + 1;
        }
    }
}

MainViewModel.cs

namespace INotifyChangedDemo
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private int _hitCount;
        public int HitCount
        {
            get
            {
                return _hitCount;
            }
            set
            {
                if (_hitCount == value)
                    return;

                _hitCount = value;
                // Notify the listeners that Time property has been changed
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("HitCount"));
                }

            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

For better implementation of INotifyChangedProperty, please refer to this thread: Automatically INotifyPropertyChanged.

If you wanna know more about the MVVM pattern, please see here: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Community
  • 1
  • 1
Shuo
  • 4,749
  • 9
  • 45
  • 63
  • Thanks for the great example! It seems like that works great if you use WPF bindings that tie a UI element to a certain property. What would happen if you weren't using bindings and didn't care in particular about a single property changing, but instead about anything at all changing about the model's state. Also, when the change occurs, I'm more interested in being able to execute a certain action on the UI (such as popping a message box) rather than updating the value of an element on the screen. Is that at all possible? – Alexandr Kurilin Nov 24 '10 at 03:25
  • @glitch:The main window can listen to the PropertyChanged event of the view model, so that when PropertyChanged is fired, the main window could open a dialog. This is the simplest solution and you need to wire up the events in every view. – Shuo Nov 24 '10 at 03:58
  • My approach to the message box problem was to have user controls which renders like message boxes where their visibility is bound to a property in the view model. Any how, overlaying of the control has to be worked out. – Ε Г И І И О Mar 08 '12 at 11:36
2

If your view binds to a property declared in your model, and your property raises the PropertyChanged event whenever it is changed, then your view will automatically be updated with the new value. For instance, your view might declare the following:

<TextBlock Text="{Binding Name}" />

And in your model you would have:

string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
        RaisePropertyChanged("Name");
    }
}

This assumes that you are using some framework / helper that provides the RaisePropertyChanged method. I am taking this example from the Galasoft MVVM framework, but I assume that exactly the same principal applies in MVC.

Hope this helps.

Mike Chamberlain
  • 39,692
  • 27
  • 110
  • 158
  • Thanks for the great example! It seems like that works great if you use WPF bindings that tie a UI element to a certain property. What would happen if you weren't using bindings and didn't care in particular about a single property changing, but instead about anything at all changing about the model's state. Also, when the change occurs, I'm more interested in being able to execute a certain action on the UI (such as popping a message box) rather than just updating the value of an element on the screen. Is that at all possible? – Alexandr Kurilin Nov 24 '10 at 03:28