I have following viewmodels:
public class ViewModel: INotifyPropertyChanged
{
public ObservableCollection<Item> Items { get; set; }
...
}
public class Item: INotifyPropertyChanged
{
public SubItem A { get; set; }
public SubItem B { get; set; }
...
}
public class SubItem: INotifyPropertyChanged
{
public bool Valid { get; set; }
...
}
xaml:
<ListBox ItemsSource="{Binding Items}" ..>
If I want to display text "Valid item"
if both A.Valid
and B.Valid
are true
, then:
I can do this by having logic in the view (item data template), e.g using visibility and extra container:
<Grid Visibility="{Binding A.Valid}" Converter=...> <TextBlock Text="Valid item" Visibility="{Binding B.Valid}" Converter=... \> </Grid>
Or I can add a new property to item viewmodel:
public class Item: INotifyPropertyChanged { public bool Valid => A.Valid && B.Valid; // bind to this ... }
The problem is that notifications of either of
SubItem
will not update the view.
In case of (1) the binding will subscribe to both PropertyChanged
events: Item
and corresponding SubItem
. In case of (2) the binding only knows about Item.Valid
property, so I have to do something like:
public class Item: INotifyPropertyChanged
{
SubItem _a;
public SubItem A
{
get { return _a; }
set
{
_a.PropertyChanged -= bla;
_a = value;
_a.PropertyChanged += bla;
OnPropertyChanged(nameof(A));
OnPropertyChanged(nameof(Valid));
}
}
void bla(object sender, PropertyChangedEventArgs e) =>
OnPropertyChanged(nameof(Valid));
...
}
Which is awful. So I prefer (1) (using data triggers sometimes, but it's irrelevant).
Are there other options to actually have viewmodel property (2) but without the hassle?