2015-08-07 3 views
0

Мне интересно, где находится тело (экземпляр) PropertyChanged?Где находится тело PropertyChanged?

private int age; 
    public int Age 
    { 
     get { return age; } 
     set 
     { 
      age = value; 
      OnPropertyChanged("age"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    void OnPropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 

В приведенном выше, «общественное событие PropertyChangedEventHandler PropertyChanged» это просто декларация, а после следующей строки вдруг PropertyChanged обработчик событий выглядит экземпляр, а затем быть в состоянии назвать. Что происходит ?

Чтобы добавить информацию, Я работаю с использованием WPF. Нет явного кода подписчика событий. Но в xaml есть ключ.

<TextBox x:Name="txtAge" Text="{Binding Age}/> 

Итак, что-то добавляет код подписчика автоматически, когда есть привязка в xaml?

ответ

0

PropertyChanged - это событие - оно будет null, если никто не подписался на это событие, иначе он будет не нулевым. Ваш пользователь API подписался бы так:

Person p = new Person(...); 
p.PropertyChanged += MyHandler; 

void MyHandler(object sender, PropertyChangedEventArgs args) { ... } 

Кроме того, ваш шаблон для нулевой проверки не на 100% безопасен. Он может измениться с нулевого значения на null после проверки.

Попробуйте это:

var callback = PropertyChanged; 
if(callback != null) { 
    callback(this, new PropertyChangedEventArgs(name)); 
} 
0

Другой объект (обычно) подпишется предоставленному обработчик события PropertyChanged.

Класс будет называть его OnPropertyChanged Событие при выполнении условий, а затем проверяет, что это поле события PropertyChanged. Если это поле не пустое, это означает, что подписчики события инициализировали его, и поэтому его можно вызвать.

Подписка будет выглядеть следующим образом:

InstanceOfYourClass.PropertyChanged += SomeFunctionThatHandlesIt; 

private void SomeFunctionThatHandlesIt(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "SomeProperty") 
    { 
     DoSomething(); 
    } 
} 
2

Это поле типа событие. Это немного похоже на автоматически реализованное свойство - компилятор C# обеспечивает реализацию. (Я бы предпочел, если синтаксис больше походили автоматически реализованы свойства, но это совсем другое дело.)

Из раздела 10.8.1 в C# 5 спецификации:

При компиляции поля типа event, компилятор автоматически создает хранилище для хранения делегата и создает аксессоры для события, которые добавляют или удаляют обработчики событий в поле делегата. Операции сложения и удаления являются потокобезопасными и могут (но не обязательно) выполняться при удерживании блокировки (§8.12) для содержащего объекта для события экземпляра или объекта типа (§7.6.10.6) для статического мероприятие.

Таким образом, объявление события экземпляра формы:

class X 
{ 
    public event D Ev; 
} 

будет скомпилирован в нечто эквивалентное:

class X 
{ 
    private D __Ev; // field to hold the delegate 
    public event D Ev { 
     add { 
      /* add the delegate in a thread safe way */ 
     } 
     remove { 
      /* remove the delegate in a thread safe way */ 
     } 
    } 
} 

В пределах класса X ссылки на Ev на левой стороне операторов + = и - = вызывают вызовы добавления и удаления доступа. Все остальные ссылки на Ev скомпилированы для ссылки на скрытое поле __Ev вместо (§7.6.4).Имя «__Ev» произвольно; скрытое поле может иметь любое имя или имя вообще.

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