2015-01-15 30 views
6

ScenariuszJak zrobić model klasy obserwowalne w WPF

uzyskać klasę modelu z urządzenia zewnętrznego lub części kodu, gdzie nie chcę aby coś zmienić. Chciałbym powiązać tę klasę z niektórym interfejsem WPF. Chciałbym również odświeżyć interfejs użytkownika, jeśli ten model zostanie zmieniony.

Pytanie

Czy naprawdę muszę napisać klasy otoki cały czas, który tworzy zdarzenia PropertyChanged dla każdego setter? W jaki sposób mogę zapobiec ręcznemu napisaniu tego kodu?

Co zaczęło tak ...

public class User : IUser 
{ 
    public String Name { get; set; } 
    public bool CurrentlyLoggedIn { get; set; } 

    // ... 
} 

... zawsze będzie nadęty jak tak

public class UserObservableWrapper : IUser, INotifyPropertyChanged 
{ 
    public String Name 
    { 
     get 
     { 
      return this.innerUser.Name; 
     } 
     set 
     { 
      if (value == this.innerUser.Name) 
      { 
       return; 
      } 

      this.innerUser.Name = value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 

    public bool CurrentlyLoggedIn 
    { 
     get 
     { 
      return innerUser.CurrentlyLoggedIn; 
     } 
     set 
     { 
      if (value.Equals(innerUser.CurrentlyLoggedIn)) 
      { 
       return; 
      } 
      innerUser.CurrentlyLoggedIn = value; 
      this.OnPropertyChanged("CurrentlyLoggedIn"); 
     } 
    } 

    private readonly IUser innerUser; 

    public UserObservableWrapper(IUser nonObservableUser) 
    { 
     this.innerUser = nonObservableUser; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Musi być bardziej inteligentny sposób to robić !?

+0

Słyszałem osób korzystających Aspect Oriented technik wstrzykiwania takiej funkcjonalności do kodu. Kasa www.PostSharp.net. Strona docelowa wspomina nawet o INotifyPropertChanged. – Crowcoder

+0

@Crowcoder http://www.postsharp.net/model/inotifypropertychanged to wygląda wspaniale, ale wymaga od niego edycji klas modelu i, jak sam określił, pochodzą one z komponentu zewnętrznego. Czy wiesz, czy 'PostSharp' ma możliwość robienia tego w czasie wykonywania? –

+0

@Moti Sam nie jestem zbyt kompetentny, więc waham się zrobić coś więcej niż powiedzieć "sprawdź to, może się przydać", ale widzę, że robią to w czasie wczytywania, a statyczne tkanie w czasie pracy brzmi, jakby nie było potrzeby zmienić rzeczywisty kod używanej biblioteki. http://www.postsharp.net/aop.net/runtime-weaving – Crowcoder

Odpowiedz

3

Jeśli nie zdarzy się to zbyt często w twoim kodzie, poleciłbym wykonanie kodu.

W przeciwnym razie możesz użyć tego cool piece of code z Ayende, aby wygenerować klasę proxy, która automatycznie zastosowałaby dla ciebie INotifyPropertyChanged (w tym podnoszenie zdarzeń). Wykorzystanie będzie wyglądać następująco:

IUser userProxy = DataBindingFactory.Create<User>();