I have a question about the PropertyChanged
event firing from a base class. So I have a base class, called MainWindowBase
with a property called SelectedItem and a collection called Items, actually derived in a lower base class. I populate Items, then set SelectedItem from the derived class, which calls the base class setter on SelectedItem. The SelectedItem.PropertyChanged
handler is never called in the derived class. Why?
class MainWindowViewModel
:
class MainWindowViewModel : MainWindowBase<DocumentBase>
{
public MainWindowViewModel()
{
Items.AddRange(new ObservableCollection<PositionViewModel>()
{
new PositionViewModel { Name = "Test Case 1" },
new PositionViewModel { Name = "Test Case 2" },
new PositionViewModel { Name = "Test Case 3" }
});
SelectedItem = Items.FirstOrDefault();
SelectedItem.PropertyChanged += (sender, args) =>
{
Debug.WriteLine("SelectedItem changed!");
};
PropertyChanged += MainWindowViewModelPropertyChanged;
SelectedItem = Items[1];
}
public void MainWindowViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
;
}
}
class MainWindowBase
:
public class MainWindowBase<TDocument> : Conductor<TDocument>.Collection.OneActive
where TDocument : DocumentBase, new()
{
private TDocument selectedItem;
public TDocument SelectedItem
{
get
{
return selectedItem;
}
set
{
selectedItem = value;
NotifyOfPropertyChange(() => SelectedItem);
}
}
}
PositionViewModel
class:
public class PositionViewModel : DocumentBase
{
public string Name { get; set; }
}
DocumentBase
is simply derived from Screen
.
Thanks for looking at this, and let me know in the comments if you need any more information. Basically Debug.WriteLine()
is never called, but MainWindowViewModelPropertyChanged()
is. I would like to just handle a property change for a specific property (SelectedItem
) in this case.
The PropertyChanged
event is fired after a property of a class was changed. Or in MSDN words:
Notifies clients that a property value has changed. [...] For example, consider a Person object with a property called FirstName.
The SelectedItem
property is defined in MainWindowBase
and inherited to MainWindowViewModel
. This means if the SelectedItem
was changed the event fires inside the class the property contains (MainWindowViewModel
in your case).
The PositionViewModel
is not recognizing if it is selected or not. The PropertyChanged
event of it is only called if a property inside itself was changed. Since you are not calling NotifyOfPropertyChange
inside the class this is never possible (except DocumentBase
is firing the event).
If you need to do specific actions at selection or deselection you can use the setter to call a method. Here is a basic example:
private TDocument selectedItem;
public TDocument SelectedItem
{
get
{
return selectedItem;
}
set
{
selectedItem?.YouAreNotSelected();
value?.YouAreSelected();
selectedItem = value;
NotifyOfPropertyChange(() => SelectedItem);
}
}