wpf - use of DependencyObject to implement data model

3578 ワード

The most common practise to implement the DataModel is by declaring the class to implements the INotifyPropertyChanged interface. 
 
However, it is one of the many ways that you can implement data model, an alternative way is to use DependencyObject. 
 
The rationale behind DependencyObject as the base class to implement data model is that it 
 
  • It has SetValue and GetValue to operate on those DependencyProperty
  • It has the OnPropertyChanged(DependencyPropertyChangedEventArgs) to notify an update is on going. 

  •  
     
    We can define our Data Model as follow.
     
        public string Message
        {
          get { return (string)GetValue(MessageProperty); }
          set {
            SetAndRaiseProeprtyChanged(MessageProperty, value);
            //SetValue(MessageProperty, value); 
          }
        }
    
        // Using a DependencyProperty as the backing store for Message.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MessageProperty =
            DependencyProperty.Register("Message", typeof(string), typeof(DataModel), new UIPropertyMetadata(string.Empty));
    
    
        private void SetAndRaiseProeprtyChanged(DependencyProperty dp, object newValue)
        {
          var oldvalue = GetValue(dp);
          SetValue(dp, newValue);
          OnPropertyChanged(new DependencyPropertyChangedEventArgs(dp, oldValue: oldvalue, newValue: newValue));
        }
    
      }
     
    and suppose that there is a view which consumes the data model, here is the view (window)
     
    <Window x:Class="DependencyObjectDemo1.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">
        <StackPanel>
            <TextBlock Name="textBlock" Text="{Binding Message}" />
            <Button Click="ChangeDataModel" Content="Click me to change DataModel"/>
        </StackPanel>
    </Window>
     
    and here is the code that connect the data model and the view. 
     
      public partial class MainWindow : Window
      {
        public MainWindow()
        {
          InitializeComponent();
    
          InitializeDataModel();
        }
    
        public void InitializeDataModel()
        {
          var dataModel = new DataModel
          {
            Message = "Hello world"
          };
    
          this.DataContext = dataModel;
        }
    
        private void ChangeDataModel(object sender, RoutedEventArgs e)
        {
          var dataModel = this.DataContext as DataModel;
          if (dataModel != null)
          {
            dataModel.Message = "New Message";
          }
        }
      }
     
     
     
    CAVEAT: it has been discussed on some other thread about the performance/memory hit by introducing the DependencyObject as the base class of Data model . Generally it is believed that the performance of DependencyObject over INotifyPropertyChanged (which is lightweighted) is that DependencyObject 's impl is slightly slower.
     
     
     
    TODO:study and research the performance  statistics to prove the performance advantage.