Search code examples
c#windows-8microsoft-metroinotifypropertychangeddependencyobject

Dependency Property vs INotifyPropertyChanged in ViewModel for Windows 8 application


I have created blank C#/XAML Windows 8 application. Add simple XAML code:

<Page
    x:Class="Blank.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel
            Margin="0,150"
            HorizontalAlignment="Center">
            <TextBlock
                x:Name="xTitle"
                Text="{Binding Title, Mode=TwoWay}"/>
            <Button Content="Click me!" Click="OnClick" />
        </StackPanel>
    </Grid>
</Page>

And the simple code in C# part:

public sealed partial class MainPage
    {
        private readonly ViewModel m_viewModel;

        public MainPage()
        {
            InitializeComponent();
            m_viewModel = new ViewModel
            {
                Title = "Test1"
            };
            DataContext = m_viewModel;
        }

        private void OnClick(object sender, RoutedEventArgs e)
        {
            m_viewModel.Title = "Test2";
        }
    }

Now I want to implement ViewModel. I have two way:

  1. Use Dependency Property
  2. Implement INotifyPropertyChanged

For first approach it is:

public class ViewModel : DependencyObject
    {
        public string Title
        {
            get
            {
                return (string)GetValue(TitleProperty);
            }
            set
            {
                SetValue(TitleProperty, value);
            }
        }

        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string)
            , typeof(ViewModel)
            , new PropertyMetadata(string.Empty));
    }

For second it is:

public class ViewModel : INotifyPropertyChanged
    {
        private string m_title;

        public string Title
        {
            get
            {
                return m_title;
            }
            set
            {
                m_title = value;
                OnPropertyChanged("Title");
            }
        }

        protected void OnPropertyChanged(string name)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

I prefer the first way, because it allows use coerce (Silverlight for web and for WP7 doesn't have coerce functionality.. WinRT too.. but I'm still looking and hope) and looks more natural for me. But unfortunately, it works as OneTime for the first approach.

Could anybody explain to me why MS abandon using Dependency Property for implementing view model?


Solution

  • You should not be using a DependencyProperty in your ViewModel - you should only use them in your controls. You will never want to bind one ViewModel to another, also ViewModels do not need to persist their values nor provide default values, nor provide property metadata.

    You should only use INotifyPropertyChanged in your ViewModels.