Работа с CheckBox у элемента ListBox. ObservableCollection

У меня есть ListBox c ObservableCollection<Model> Models. В ListBox есть CheckBox, у которого привязка IsVisualizationModel

View:

<Window.Resources>
     <local:Model x:Key="models"/>
</Window.Resources>
<ListBox ItemsSource = "{Binding Models}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                        <CheckBox IsChecked="{Binding Source={StaticResource models}, Path=IsVisualizationModel}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Model:

 public class Model : INotifypropertyChanged
 {
    private bool isVisualizationModel;
    public bool IsVisualizationModel
    {
        get { return isVisualizationModel; }
        set
        {
            isVisualizationModel = value;
            OnPropertyChanged();
        }
    } 
// interface implementation
 }

Проблема в том, что Model у меня целый список и далее в коде я его перебираю, проверяя свойство IsVisualizationModel. При проверке всегда получаю false, хотя привязка срабатывает и устанавливает свойство в true. Видимо привязка изменяет свойство не текущего элемента списка(ObservableCollection Models). Наверное, стоит как-то использовать ICommand, чтобы передать конкретный экземпляр списка и у него изменить свойство IsVisualizationModel. Я не знаю как это правильно реализовать. К тому же у меня тут никак не задействована ViewModel, что мне тоже кажется не правильным.


Ответы (1 шт):

Автор решения: aepot

Вы перемудрили.

Вот просто вот так должно заработать

<ListBox ItemsSource="{Binding Models}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsVisualizationModel}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Ошибки

Вот этот xaml:

<local:Model x:Key="models"/>

логически эквивалент этого C#:

dictionary.Add("model", new Model());

то есть, вы создаете один экземпляр класса Model и кладете его в словарь ресурсов. Зачем? Уберите это совсем.

К тому же, как @EvgeniyZ верно подметил в комментариях:

Задавать в XAML источник данных вообще является нарушением MVVM и вот почему.

Source={StaticResource models} указывает на что что надо прибиндить каждый чекбокс из ListBox в общему свойству, которое находится в единственном экземпляре класса Model, хранимом в словаре ресурсов окна. В этом случае должно работать так, что при изменении любого из чекбоксов, изменяются все одновременно.

Другими словами, ничего нового писать не нужно, а просто убрать изобретение.

Почему это рабоотает:

<CheckBox IsChecked="{Binding IsVisualizationModel}"/>

А потому что ItemsSource="{Binding Models}" задает DataContext каждому элементу списка ListBox, указывающий на элемент привязанной коллекции.

То есть DataContext здесь {Binding Models} и здесь {Binding IsVisualizationModel} - два разных контекста. Первый - это экземпляр класса MainViewModel второй - текущий элемент в коллекции Models типа ObservableCollection<Model>.

И почему кстати класс назвали Model? Если отталкиваться от его функции, я бы его назвал ListBoxItemViewModel.

→ Ссылка