Как изменить данные в каждом элементе в ObservableCollection? - PullRequest
3 голосов
/ 25 сентября 2019

У меня есть такая структура в XAML, где каждый элемент имеет флажок.

□ Fruits
   □ Apple
   □ Banana
   □ Orange

Моя цель - иметь функцию, которая, если установлен флажок Fruit's , будет проверять все (выбрать все) фрукты.

Так что я связываю свои ViewModel's function в моем Checkbox's IsChecked.

<TreeView
    ItemsSource="{Binding Foods}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type domain:Food}" ItemsSource="{Binding Fruits}">
            <StackPanel Orientation="Horizontal">
                <CheckBox
                    IsChecked="{Binding SelectAll}"
                    />
                <TextBlock Text="   "/>
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type domain:Fruit}">
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

Моя ViewModel это:

private bool _selectAll = false;

public bool SelectAll
{
    get
    {
        return _selectAll;
    }
    set
    {
        foreach (var item in Fruits)
        {
            item.isSelected = true;
        }
    }
}

Редактировать

public class Food
{
    public string Name { get; set; }
    public ObservableCollection<Fruit> Fruits { get; set; } = new ObservableCollection<Fruit>();
}

public class Fruit
{
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

Но ничего не происходит.

1 Ответ

2 голосов
/ 25 сентября 2019

Я не совсем уверен, что вы ожидали, но с XAML, приведенным в Вопросе, у меня даже не было флажков перед именами отдельных фруктов, поэтому мне пришлось немного отредактировать XAML:

<TreeView
    ItemsSource="{Binding Foods}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type domain:Food}" ItemsSource="{Binding Fruits}">
            <StackPanel Orientation="Horizontal">
                <CheckBox
                    IsChecked="{Binding SelectAll}" />
                <TextBlock Text="   " />
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type domain:Fruit}">
            <!-- Here I added the StackPanel and the CheckBox -->
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsSelected}" />
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

После этого я сделал некоторые изменения в коде, в основном я просто реализовал INotifyPropertyChanged.Итак, класс Food and Fruit теперь выглядит так:

public class Food
{
    public string Name { get; set; }

    public ObservableCollection<Fruit> Fruits { get; set; }

    private bool _selectAll;

    public bool SelectAll
    {
        get => _selectAll;
        set
        {
            _selectAll = value;
            foreach (var f in Fruits)
                f.IsSelected = value;
        }
    }
}

И Fruit вроде этого

public class Fruit : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool _isSelected;

    public bool IsSelected
    {
        get => _isSelected;
        set
        {
            _isSelected = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Редактировать: INotifyPropertyChanged не требуется для Food

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...