MVVM - binding to aggregated property

I have the following view modes:

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.Validand B.Validare equal true, then:

  • I can do this with the logic in the view (element data template), for example, using visibility and an additional container:

    <Grid Visibility="{Binding A.Valid}" Converter=...>
        <TextBlock Text="Valid item" Visibility="{Binding B.Valid}" Converter=... \>
    </Grid>
    
  • Or I can add a new property in the viewmodel item:

    public class Item: INotifyPropertyChanged
    {
        public bool Valid => A.Valid && B.Valid; // bind to this
        ...
    }
    

    The problem is that notifications of any of these SubItemwill not update the view.

In case (1), the binding will be subscribed to both events PropertyChanged: Itemand matches SubItem. In case (2), the binding only knows about the property Item.Valid, so I need 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));
    ...
}

It's horrible. So I prefer (1) (data triggers are sometimes used, but that doesn't matter).

, viewmodel (2), ?

+1
1

. , WPF , , .

, , - - . Valid SubItem , , . Item, , , A B, Valid.

. -, - ViewModel. , Item ( ). , , , , , WPF IMO.

0

Source: https://habr.com/ru/post/1693978/


All Articles