2011-01-13 7 views
4

私はいくつかのクラスの静的プロパティをいくつかのコントロールにバインドしようとしています。私はいくつかの実装をtryiedましたが、それぞれがその問題を持っています静的プロパティをバインドし、INotifyPropertyChangedを実装する

すべての例は次のXAMLを使用します。

<Label Name="label1" Content="{Binding Path=text}"/> 

第一のアプローチ - INotifyPropertyChangedの

public class foo1 
{ 
    public static string text { get; set; } 
} 

を使用していない問題があることです'text'特性が変更された場合、制御は通知されません。

第二のアプローチ - OnPropertyChangedを()メソッドは静的ではありません、それは静的メソッド内で呼ばれていますので、これはコンパイルされませんINotifyPropertyChangedの

public class foo1 : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private static string _text; 
    public static string text 
    { 
     get { return _text; } 
     set 
     { 
      _text = value; 
      OnPropertyChanged("text"); 
     } 
    } 
} 

を使用しています。

2番目のアプローチtry 2:Make OnPropertyChanged()method static => OnPropertyChanged()は静的であり、静的ではない 'PropertyChanged'イベントを使用しようとするため、これはコンパイルされません。

2番目のアプローチtry 3:make 'PropertyChanged' event static =>クラスが 'INotifyPropertyChanged.PropertyChanged'イベントを実装していないためコンパイルされません( 'INotifyPropertyChangedインターフェイスは静的ではありませんが、静的)。

この時点で私はあきらめました。

すべてのアイデア?

private static string _text; 
public string text 
{ 
    get { return _text; } 
    set 
    { 
     _text = value; 
     OnPropertyChanged("text"); 
    } 
} 

は、しかし、これは変更通知のみの1つのインスタンスで作成されているので、比較的無意味な結合全体を行います

答えて

10

私はあなただけインスタンスプロパティは、このようなあなたの静的プロパティを返す必要があり お勧めしたいですすべてのインスタンスではありません。したがって、変更された特定のインスタンスのプロパティにバインドするバインディングのみが更新されます。

より良い方法は、hereのようにシングルトンを使用することです。

2

シングルトンを使用することは、実装するのが最も簡単でクリーンな方法です。シングルトンを使わずに邪魔にならないようにするには、次のようにすることができます。

静的プロパティから呼び出される静的PropertyChangedEventHandlerを作成します。クラスの新しいインスタンスを作成するときは、登録して静的イベントからコールバックを受け取ります。コールバックを取得したら、OnPropertyChanged( "text")を呼び出します。 この大きな問題は、静的イベントの登録時にWeakReferenceを使用する必要があることです。それ以外の場合は、オブジェクトは永遠に残っています。コードのこのステップをスキップしました。

史上登録者NotifyPropertyChangedを知っている必要があるので、あなたがインスタンスイベントに転送する必要がある理由は、誰送信者(その上のインスタンス・プロパティとfoo1ののすなわちインスタンス)

public class foo1 : System.ComponentModel.INotifyPropertyChanged 
{ 
    // static property 
    private static string _text = "static string"; 
    public static string static_text 
    { 
     get 
     { 
      return _text; 
     } 
     set 
     { 
      _text = value; 
      OnStaticPropertyChanged("static_text"); 
     } 
    } 
    private static System.ComponentModel.PropertyChangedEventHandler staticpropChanged; 
    static protected void OnStaticPropertyChanged(string pname) 
    { 
     System.ComponentModel.PropertyChangedEventArgs e = new System.ComponentModel.PropertyChangedEventArgs(pname); 
     System.ComponentModel.PropertyChangedEventHandler h = staticpropChanged; 
     if (h != null) 
      h(null, e); 

    } 
    public foo1() 
    { 
     // really should use a weakreference here.. but leaving it out 
     // for simplicity 
     staticpropChanged += foo1_staticpropChanged; 
    } 

    void foo1_staticpropChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
    { 
     // map the static name to the instance name 
     if(e.PropertyName == "static_text") OnPropertyChanged("text"); 
    } 
    // instance-property forwards to static 
    public string text 
    { 
     get { return foo1.static_text; } 
     set { foo1.static_text = value; } 
    } 
+0

私は少し異なる –

0
public static String StatusInformation 
    { 
     get { return _StatusInformation; } 
     set { _StatusInformation = value; OnStaticPropertyChanged("StatusText"); } 
    } 

    #region Handlig Static Properties Changed 
    private static System.ComponentModel.PropertyChangedEventHandler staticpropChanged; 
    static protected void OnStaticPropertyChanged(string pname) 
    { 
     System.ComponentModel.PropertyChangedEventArgs e = new System.ComponentModel.PropertyChangedEventArgs(pname); 
     System.ComponentModel.PropertyChangedEventHandler h = staticpropChanged; 
     if (h != null) 
      h(null, e); 

    } 
    private void Handler_PropertyChange(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
    { 
     NotifyPropertyChanged(e.PropertyName); 
    } 
    #endregion 
    public string StatusText 
    { 
     get { return ExchangeServices.StatusInformation; } 
     set { ExchangeServices.StatusInformation = value; } 
    } 

このようにして、私はこのイベントで何の処理もしなくて済むようになりました。 これは、私のプログラム全体に対して一つのステータスバーを作成し、いつでも拡張しているプログラムのどこからでも、どんなユーザコントロールからでもそれを更新するのに本当に役に立ちました。

ありがとうshimpossible

関連する問題