2011-01-13 3 views
4

Я пытаюсь связать статическое свойство некоторого класса с некоторым элементом управления. Я tryied несколько реализации, но каждый из них имеет свою задачу:Связывание статического свойства и реализация INotifyPropertyChanged

Все примеры используют следующий код XAML:

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

первого подход - не использовать INotifyPropertyChanged

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

Проблема заключается в том, что когда «текст» изменяется, элемент управления не уведомляется.

Второй подход - использовать 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"); 
     } 
    } 
} 

Это не компилируется, так как метод OnPropertyChanged() не является статическим, и это называется в статическом методе.

Второй подход try 2: make OnPropertyChanged() метод static => это не скомпилируется, потому что OnPropertyChanged() теперь статичен и пытается использовать событие «PropertyChanged», которое не является статичным.

Второй подход try 3: make 'PropertyChanged' event static => это не скомпилируется, потому что класс не реализует событие INotifyPropertyChanged.PropertyChanged (событие определено в интерфейсе INotifyPropertyChanged не является статическим, но здесь оно статика).

На данный момент я сдался.

Любые идеи?

ответ

10

Я предлагаю вы просто экземпляр-свойство вернуть статическое свойство как это:

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

Однако это делает весь связывающую сравнительно бессмысленно, так как уведомления об изменениях создаются только в одном случае из класс, а не каждый экземпляр. Таким образом, будут обновляться только привязки, которые привязаны к свойству в конкретном экземпляре, на котором он был изменен.

Лучшим методом будет использование синглета, как можно видеть here.

2

Использование синглтона будет самым простым и чистым в реализации. Если вы хотите пройти жесткий путь без использования сингла, вы можете использовать следующее.

Создайте статический PropertyChangedEventHandler, который вызывается из вашего статического свойства. Когда вы создаете новый экземпляр своего класса, зарегистрируйтесь для получения обратного вызова из статического события. Когда вы получите обратный вызов, вызовите OnPropertyChanged («текст»). Проблема BIG с этим - вам нужно использовать 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; } 
    } 

таким образом, я не должен был выполнять никаких действий в случае вообще. было очень полезно создать одну строку состояния для всей моей программы и обновить ее из любого места и любого пользовательского элемента управления в моей постоянно расширяющейся программе.

Благодарим за помощь

Смежные вопросы