I have a custom control which is inherited from TextBox control.
I would like to implement the INotifyPropertyChanged
interface in my custom control.
the PropertyChanged event handler is alwas null.
This will always be true until something subscribes to the PropertyChanged
event.
Typically, if you're making a custom control, however, you wouldn't use INotifyPropertyChanged
. In this scenario, you'd make a Custom Dependency Property instead. Normally, the dependency objects (ie: controls) will all use Dependency Properties, and INPC is used by the classes which become the DataContext
of these objects. This allows the binding system to work properly.
The PropertyChanged event is used by UI code, but not in that sense you are writing. Controls never implement INPC (short for INotifyPropertyChanged), they are bound to object that have implemented INPC. This way certain UI properties, e.g. the Text property on the TextBox control is bound to a property on such class. This is the basis of MVVM architecture.
Example, you would write the following XAML code:
<TextBlock x:Name="txtBox" Text="{Binding Title}" />
And you set the data context for TextBlock (or any of its ancestors, DataContext is propagated) in the code in the following manner:
txtBox.DataContext = new Movie {Title = "Titanic"};
And now for the class itself:
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");
}
}
}
Now, whenever you change the Title property
, whether in the code or via other binding, UI will be automatically refreshed. Here's more information about Data Binding and MVVM.
Do it like I said in the comments.
It doesnt work like you did. Just create an extra class and implement Notification Interface
there and apply this class to the DataContext
of the UserControl
. And it will work like you need.
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));
}
}