2012-09-17 17 views
9

Tengo un control personalizado que se hereda del control TextBox. Me gustaría implementar la interfaz INotifyPropertyChanged en mi control personalizado.INotifyPropertyChanged en UserControl

public class CustomTextBox : TextBox, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 
} 

Mi problema es cuando intento planteado un evento PropertyChanged el controlador de eventos PropertyChanged siempre es nula.

¿Alguien me puede ayudar?

+0

No funciona como usted. Simplemente cree una clase adicional e implemente la Interfaz de notificación allí y aplique esta clase al DataContext del UserControl. Y funcionará como lo necesites. –

Respuesta

12

el controlador de eventos PropertyChanged es siempre nulo.

Esto siempre será así hasta que algo se suscriba al evento PropertyChanged.

Por lo general, si está haciendo un control personalizado, sin embargo, no usaría INotifyPropertyChanged. En este escenario, harías un Custom Dependency Property en su lugar. Normalmente, los objetos de dependencia (es decir, los controles) usarán Propiedades de dependencia, e INPC será utilizado por las clases que se convierten en el DataContext de estos objetos. Esto permite que el sistema de enlace funcione correctamente.

6

¿Qué esperabas? El código de UI utiliza el evento PropertyChanged, pero no en el sentido en que está escribiendo. Los controles nunca implementan INPC (abreviatura de INotifyPropertyChanged), están obligados a objetar que han implementado INPC. De esta manera, ciertas propiedades de la interfaz de usuario, p. la propiedad Text en el control TextBox está vinculada a una propiedad en dicha clase. Esta es la base de la arquitectura MVVM.

ejemplo, podría escribir el siguiente código XAML:

<TextBlock x:Name="txtBox" Text="{Binding Title}" /> 

y se establece el contexto de datos para TextBlock (o cualquiera de sus ascendientes, DataContext se propaga) en el código de la siguiente manera:

txtBox.DataContext = new Movie {Title = "Titanic"}; 

Y ahora para la propia clase:

public class Movie : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 

    private string _title; 
    public string Title 
    { 
     get { return _title; } 
     set 
     { 
      if (_title == value) return; 

      _title = value; 
      NotifyPropertyChanged("Title"); 
     } 
    } 
} 

ahora, cada vez que CH La propiedad del título, ya sea en el código o a través de otro enlace, la interfaz de usuario se actualizará automáticamente. Google for Data Binding y MVVM.

+2

Esto actualiza el control cada vez que los datos cambian, pero supongo que el OP está intentando implementar el enlace de dos vías donde el UserControl actualiza automáticamente la fuente de datos. Es de suponer que hay alguna manera de notificar que el control del usuario ha actualizado la propiedad, pero aún no lo he encontrado. – misnomer

1

Hazlo como dije en los comentarios. No funciona como lo hiciste. Simplemente cree una clase extra e implemente Notification Interface allí y aplique esta clase al DataContext del UserControl. Y funcionará como lo necesites.

public partial class W3 : UserControl 
    { 
     WeatherViewModel model = new WeatherViewModel(); 

     public W3() 
     { 
      InitializeComponent(); 
      this.DataContext = model; 
     } 

     public void UpdateUI(List<WeatherDetails> data, bool isNextDays) 
     { 
      model.UpdateUI(data, isNextDays); 
     } 
    } 

    class WeatherViewModel : INotifyPropertyChanged 
    {  

     public void UpdateUI(List<WeatherDetails> data, bool isNextDays) 
     { 
      List<WeatherDetails> weatherInfo = data; 
      if (weatherInfo.Count != 0) 
      { 
       CurrentWeather = weatherInfo.First(); 
       if (isNextDays) 
        Forecast = weatherInfo.Skip(1).ToList(); 
      } 
     } 

     private List<WeatherDetails> _forecast = new List<WeatherDetails>(); 

     public List<WeatherDetails> Forecast 
     { 
      get { return _forecast; } 
      set 
      { 
       _forecast = value; 
       OnPropertyChanged("Forecast"); 
      } 
     } 

     private WeatherDetails _currentWeather = new WeatherDetails(); 

     public WeatherDetails CurrentWeather 
     { 
      get { return _currentWeather; } 
      set 
      { 
       _currentWeather = value; 
       OnPropertyChanged("CurrentWeather"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void OnPropertyChanged(string propertyName) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    }