2016-07-07 5 views
1

私はWPFとMVVMモデルで作業しています。私はViewModelBaseと呼ばれる基本的なviewmodelクラスを持っています。複雑なタイプのConfigというプロパティがあります。ビューの基本クラスのConfigプロパティにデータバインドできるようにするには、派生クラスが必要です。INotifyPropertyChangedとBaseClassのプロパティC#

public class ViewModelBase : INotifyPropertyChanged 
{ 
    private Configuration _config; 
    public event PropertyChangedEventHandler PropertyChanged; 

    public Configuration Config 
    { 
     get { return _config; } 
     set 
     { 
      if(_config == null || !_config.Equals(value)) 
      { 
       _config = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("Config")); 
      } 
     } 
    } 

    public ViewModelBase() 
    { 
    } 

    public void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if(PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 
} 

データバインディングは、読み出し容量で動作しているようだが、構成のプロパティはOptionsViewに変更されるとき、変更が構成自体には反映されません。助言がありますか?

要求ごとの構成の実装。ここで

public class Configuration : IEquatable<Configuration>, INotifyPropertyChanged 
{ 
    private string _primaryUrl; 
    private string _secondaryUrl; 
    private DateTime _scheduledStart; 
    private DateTime _scheduledEnd; 
    private string _buffer; 
    private bool _isScheduleEnabled; 
    private int _logDays; 
    private int _retryDuration; 
    private int _maxRetryAttempts; 
    private string _registrationKey; 
    private string _email; 

    public string PrimaryURL 
    { 
     get { return _primaryUrl; } 
     set 
     { 
      if(_primaryUrl != value) 
      { 
       _primaryUrl = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("PrimaryURL")); 
      } 
     } 
    } 
    public string SecondaryURL 
    { 
     get { return _secondaryUrl; } 
     set 
     { 
      if(_secondaryUrl != value) 
      { 
       _secondaryUrl = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("SecondaryURL")); 
      } 
     } 
    } 
    public DateTime ScheduledStart 
    { 
     get { return _scheduledStart; } 
     set 
     { 
      if(_scheduledStart != value) 
      { 
       _scheduledStart = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("ScheduledStart")); 
      } 
     } 
    } 
    public DateTime ScheduledEnd 
    { 
     get { return _scheduledEnd; } 
     set 
     { 
      if(_scheduledEnd != value) 
      { 
       _scheduledEnd = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("ScheduledEnd")); 
      } 
     } 
    } 
    public string Buffer 
    { 
     get { return _buffer; } 
     set 
     { 
      if(_buffer != value) 
      { 
       _buffer = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("Buffer")); 
      } 
     } 
    } 
    public bool IsScheduleEnabled 
    { 
     get { return _isScheduleEnabled; } 
     set 
     { 
      if(_isScheduleEnabled != value) 
      { 
       _isScheduleEnabled = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("IsScheduleEnabled")); 
      } 
     } 
    } 
    public int LogDays 
    { 
     get { return _logDays; } 
     set 
     { 
      if(_logDays != value) 
      { 
       _logDays = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("LogDays")); 
      } 
     } 
    } 
    public int RetryDuration 
    { 
     get { return _retryDuration; } 
     set 
     { 
      if(_retryDuration != value) 
      { 
       _retryDuration = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("RetryDuration")); 
      } 
     } 
    } 
    public int MaxRetryAttempts 
    { 
     get { return _maxRetryAttempts; } 
     set 
     { 
      if(_maxRetryAttempts != value) 
      { 
       _maxRetryAttempts = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("MaxRetryAttempts")); 
      } 
     } 
    } 
    public string RegistrationKey 
    { 
     get { return _registrationKey; } 
     set 
     { 
      if(_registrationKey != value) 
      { 
       _registrationKey = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("RegistrationKey")); 
      } 
     } 
    } 
    public string Email 
    { 
     get { return _email; } 
     set 
     { 
      if(_email != value) 
      { 
       _email = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("Email")); 
      } 
     } 
    } 

    public Configuration() { } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if(PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 
} 

は犯人バインディングのいずれかです。

<xctk:DateTimePicker Grid.Column="1" Value="{Binding Config.ScheduledStart}" Height="20" VerticalAlignment="Top"/> 
+2

'Configuration'は' INotifyPropertyChanged'を実装していますか? –

+0

コードに何も問題はないようです。私は実行時にあなたのデータバインディングを調べるためにSnoopを使用したいと思います。 – Will

答えて

1

INotifyPropertyChangedの実装は、クラスに直接適用されます。あなたのケースでは、ViewModelBaseクラスとそのサブタイプになります。この場合

PropertyChangedEventConfigプロパティのセッターに上昇するので、Configプロパティが設定され(およびセッターが呼び出される)たびに、イベントが発生されます。

しかしこれは、突然変異Configのオブジェクトもまた上がっていることを意味しません。一般的に、これは当てはまりません。

Configオブジェクトが変更されたときにイベントを発生させるには、オブジェクトをビューモデルに再割り当てする必要があります(セッターを再度呼び出す)。しかし、これはオブジェクトへのデータのバインディング時には機能しません。

もっと良い解決策は、にINotifyPropertyChangedインターフェイス自体を実装することです。そのオブジェクト内のプロパティが変更されると、イベントも発生します。 WPFはこれをサブオブジェクトに対しても認識しますので、自動的に機能します。

+0

私は既にINotifyPropertyChangedを実装しているConfigurationを持っています –

+0

実装が正しいなら、それは動作しているはずです。おそらく 'Configuration'の実装を質問に追加しますか?リクエストごとに – poke

+0

が編集されました。 –

1

データバインディングは、リードキャパシティで動作しているようだ ...

細かいですが、

あなたが変更したい場合クラスConfigurationINotifyPropertyChangedに準拠する必要があり、クラスの各プロパティは変更の通知をPropertyChangeに報告する必要があります結合されたxamlコントロールに表示されます。

が、コンフィグのプロパティはOptionsViewに変更されたときに、変更がConfigurationインスタンスを交換した場合、あなたが今だけ通知してきた何

に反映されません。個々のプロパティの変更ではありません内の現在のインスタンス。

関連する問題