2016-09-09 3 views
0

私のクラスのプロパティ宣言を単純化したいと思います。問題はゲッターとセッターの定義です。私は何百ものプロパティについて全く同じことをしています。すべてのプロパティは、このように作成され、メソッド "LogPropertyChanged"もRaisePropertyChangeです。mvvmオブジェクトを単純化するWPF

public class PCS_MA_V1_ALARMSTAT : ViewModelBase 
{ 
    private Boolean _ActionAlarmHighHigh; 
    public Boolean ActionAlarmHighHigh 
    { 
     get 
     { 
      return _ActionAlarmHighHigh; 
     } 
     set 
     { 
      if(value!= _ActionAlarmHighHigh) 
      { 
       _ActionAlarmHighHigh = value; 
       LogpropertyChanged("ActionAlarmHighHigh", oldVal, newVal); 
      } 

     } 
    } 
    private Boolean _ActionAlarmLowLow; 
    public Boolean ActionAlarmLowLow 
    { 
     get 
     { 
      return _ActionAlarmLowLow; 
     } 
     set 
     { 
      if(value!= _ActionAlarmLowLow) 
      { 
       _ActionAlarmLowLow = value; 
       LogpropertyChanged("ActionAlarmLowLow", oldVal, newVal); 
      } 

     } 
    } 
} 

今、私はこの構文が複雑にずっといると思う、とで動作するように巨大なハスレ。

public class PCS_MA_V1_ALARMSTAT: ViewModelBase 
{ 
    public Boolean ActionAlarmHighHigh { get; set; } 
    public Boolean ActionAlarmLowLow { get; set; } 
} 

このようなクラスを作成する方法はありますか?プロパティが変更された場合は、その特定のプロパティでLogPropertyChangedを実行します。これは可能ですか?

+2

あなたは今日この質問をするのが二番目です。あなたの答えは「いいえ」です。ここで行うことは、フィールドを設定し、値が変更された場合には 'PropertyChanged'を発生させるSetProperty (ref T propertyField、[CallerMemberName] String propName = null)'メソッドを記述することです。ところで、私は少なくともLogPropertyChangedという名前を、それがMERELYがロギングすることを意味しない何かにリネームするでしょう。メソッドのための悪い考えではなく、非常に誤解を招く名前。 –

+0

Visual Studioを使用している場合は、[スニペットを書き込む](https://swissarmycrowbar.wordpress.com/2016/07/19/viewmodel-property-snippets-c6/)を使用してプロパティ定義を作成します。 –

+0

@EdPlunkett私はすでにこれらのクラスを生成するプログラムを作成しました。何千もの行を作成します。問題は、今でも私もそのアプリケーションを維持しなければならないということです;)あなたが時間があれば、私はあなたの答えをコードであまりにも魅力的にするでしょう。私はあなたのアプローチにそれを実装する方法がわからない。 – Snovva1

答えて

0

残念ながら、getsetのデフォルト動作を上書きすることはできません。

できることはViewModelBaseと書いてください。それは共通のイディオムです。私のコードは大部分がfrom this answerで、PrismのBindableBasea similar SetProperty<T> methodですが、私はその実装を検討しませんでした。それほど多くのことはできません。

using System; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 

namespace HollowEarth.MVVM 
{ 
    public class ViewModelBase : INotifyPropertyChanged 
    { 
     #region SetProperty 
     protected virtual bool SetProperty<T>(ref T backingField, 
      T newValue, 
      [CallerMemberName] String propName = null) 
     { 
      if (EqualityComparer<T>.Default.Equals(backingField, newValue)) 
      { 
#if DEBUG 
       System.Diagnostics.Trace.WriteLine(
        $"No change in {propName} == {backingField}"); 
#endif 
       return false; 
      } 

#if DEBUG 
      System.Diagnostics.Trace.WriteLine(
       $"Changing {propName} from {backingField} to {newValue}"); 
#endif 

      backingField = newValue; 
      OnPropertyChanged(propName); 

      return true; 
     } 
     #endregion SetProperty 

     #region INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(
      [CallerMemberName] String propName = null) 
     { 
      PropertyChanged?.Invoke(this, 
       new PropertyChangedEventArgs(propName)); 
     } 
     #endregion INotifyPropertyChanged 
    } 
} 

そしてそうのようにそれを使用します。

public class MyViewModel : ViewModelBase 
{ 
    #region Whenever Property 
    private DateTime? _whenever = default(DateTime?); 
    public DateTime? Whenever 
    { 
     get { return _whenever; } 
     set { SetProperty(ref _whenever, value); } 
    } 
    #endregion Whenever Property 
} 

私はプロパティを生成するVisual Studio snippetsを書きます。あなたはプログラムでこのようなものを生成していると言っているので、スニペットは即時の要件ではありませんが、それは覚えておいてください。

生成されたコードの保守性が懸念される場合は、部分クラスを使用することもできます。生成されたコードを手で編集しない別々のファイル(WinformsのForm1.Designer.cs/Form1.resxとよく似ています)に入れ、入力のファイルを生成するために使用します。入力ファイルが何であれビルドアクションとしてジェネレータを設定します。

メンテナンスの対象となるメタレベルについては、Perlで部分クラスジェネレータを記述してください。