2017-12-09 5 views
2

PropertyChangedイベントハンドラで古い値、新しい値とプロパティ名を取得する必要があります。 INotifyPropertyChangedのデフォルトの実装では、プロパティの名前のみが提供されます。インターネット上で検索した結果、プロパティの拡張実装が変更されたのと同様の質問がありました。以下はC#でPropertyChangedイベントのINotifyPropertyChanged実装で古い値と新しい値を取得する方法

そのQとのインタフェース宣言へのリンクです:

NotifyPropertyChanged event where event args contain the old value

public interface INotifyPropertyChangedExtended<T> 
{ 
    event PropertyChangedExtendedEventHandler<T> PropertyChanged; 
} 

パブリックデリゲート無効PropertyChangedExtendedEventHandler(オブジェクト送信者、PropertyChangedExtendedEventArgs E)。

上記のインターフェイスで問題は解決しますが、プロパティのデータ型によってTが変わるため、Entityクラスに汎用インターフェイスを実装する方法がわかりません。

誰でも私を理解する助けができますか?Tパラメータでこのインターフェイスを実装することは可能でしょうか。これのサンプル実装は本当に役に立ちます。

ご協力いただきありがとうございます。

Umesh

EDIT#1:ピーターからの回答をもとに 、PropertyChangedイベントに古い値と新しい値をキャプチャしたい人のために有用である可能性が更新されたコードを掲示します。

public class PropertyChangedExtendedEventArgs : PropertyChangedEventArgs 
{ 
    public string OldValue { get; set; } 

    public string NewValue { get; set; } 

    public PropertyChangedExtendedEventArgs(string propertyName, string oldValue, string newValue) : base(propertyName) 
    { 
     OldValue = oldValue; 
     NewValue = newValue; 
    } 
} 

    // 
// Summary: 
//  Notifies clients that a property value has changed. 
public interface INotifyPropertyChangedEnhanced 
{ 
    // 
    // Summary: 
    //  Occurs when a property value changes. 
    event PropertyChangedEventHandlerEnhanced PropertyChanged; 
} 

public delegate void PropertyChangedEventHandlerEnhanced(object sender, PropertyChangedExtendedEventArgs e); 

public abstract class BindableBase : INotifyPropertyChangedEnhanced 
{ 
    public event PropertyChangedEventHandlerEnhanced PropertyChanged; 

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] 
    string propertyName = null) 
    { 
     if (Equals(storage, value)) 
     { 
      return false; 
     } 

     var oldValue = storage; 
     storage = value; 
     this.OnPropertyChanged(oldValue, value, propertyName); 
     return true; 
    } 
    protected void OnPropertyChanged<T>(T oldValue, T newValue, [CallerMemberName] string propertyName = null) 
    { 
     this.PropertyChanged?.Invoke(this, new PropertyChangedExtendedEventArgs(propertyName, oldValue?.ToString(), newValue?.ToString())); 
    } 
} 

答えて

1

私はTが正しいのプロパティ

のデータ型に応じて変化しますので、私のエンティティクラスのジェネリックインターフェイスを実装する方法を理解していないのです。あなたが見ている答えは、コンパイルや意味のないコードが含まれているため、実際にはすべて答えが良いというわけではありません。

非ジェネリックPropertyChangedEventArgsクラスを継承し、一般的な引数のクラスを渡すことによって、非ジェネリックPropertyChangedイベントを上げるの基本的な考え方は、それ自体で大丈夫です。あなたのケースではうまくいくはずです。

しかし!あなたは、回答が提案する汎用インターフェースを実装することはできません。なぜなら、プロパティーが異なるタイプを持つ場合、インターフェースは機能しないからです(すでにメモしておきます)。実際には、イベントの発生方法自体が汎用的であり、非汎用のPropertyChangedイベント(このメソッドはジェネリックインターフェイスと互換性がない)が発生するため、あなたが見ている答えはそのインターフェイスでコンパイルされません。彼らはジェネリックインターフェイスを実際に実装するのは面倒ではありません(試してみたらジェネリックメソッドがジェネリックインターフェイス&hellipで動作しないことに気づいたでしょう;メソッドのタイプパラメータTはインターフェイスのタイプパラメータTと異なります) 。

非常に高い投票率の答えがそのように書かれたことは残念です。それにはいくつかの便利なアイデアがありますが、それも完全に実行不可能なアイデアを持っています。そして、そのような答えを探している人たちを正確に混同します。最も答えを読んで使用したいと思っている人たち)。

+0

ありがとうございました。 Tを使う代わりに、古い値と新しい値の文字列型を使って解決しました。監査の場合は、各プロパティの古い値と新しい値を取得し、DBに格納してレポートする必要があります。 –

0

できません。 INotifyPropetyChangingも実装します。それは古い値へのアクセスを提供します。両方のインターフェイスのサンプル実装はドキュメントにあります。

関連する問題