С какими флажками связаны? Если он привязан к свойству объектов в вашей коллекции, вам не нужно выяснять, какой флажок был выбран. Если он не привязан к чему-либо на объекте или в ViewModel, вы можете получить SelectedItem из списка.
Ранее я привязал свойство SelectedItem listBox к свойству в моей ViewModel, чтобы у меня могли быть вещи, которые запускаются при каждом его изменении.
Что касается получения индекса, вы должны быть в состоянии сопоставить idex, возвращенный из списка, с индексом элемента в CollectionViewSource.View, который содержит текущее представление коллекции в порядке ее отображения.
Если вы не используете MVVM, я бы предложил это. Я начал не использовать его и быстро погряз в коде.
Пример в MVVM
Допустим, у нас есть MyClass с тремя строковыми свойствами и логическим значением. В MVVM у нас есть MyClassViewModel, у которого есть свойство содержать экземпляр MyClass вместе со всеми необходимыми функциями для представления (элемент списка в данном случае). У нас также есть MyWindowViewModel, который будет содержать коллекцию данных и другие вещи для нашего основного представления.
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
Пример ViewModels
Public Class MainViewModel
Inherits ViewModelBase
Public Property MyClassCollection as New ObservableCollection(Of MyClassViewModel)
End Class
Public Class MyClassViewModel
Inherits ViewModelBase
Public Property ModelClass as MyClass
Public Sub New()
End Sub
Public Sub New(ByRef CustClass as MyClass)
ModelClass = CustClass
End Sub
End Class
Когда мы получаем наши данные, мы помещаем их в коллекцию ObservableCollection (Of MyClassViewModel). Я обычно делаю это в обработчике WorkCompleted для фонового работника по поиску данных.
For Each mc as MyClass in e.Results
MyClassCollection.Add(New MyClassViewModel(mc)
Next
Список будет по-прежнему получать свои элементы из наблюдаемой коллекции через collectionViewSource, но теперь они будут иметь тип MyClassViewModel.
<DataTemplate DataType="{x:Type local:MyClassViewModel}">
<Border BorderBrush="#FF036200" BorderThickness="1" Background="#FF3CC600" CornerRadius="10">
<Grid Height="Auto" Margin="4" DataContext={Binding ModelClass}>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding StringProp1}" VerticalAlignment="Top" Margin="0" FontSize="16"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding StringProp2}" VerticalAlignment="Top" Margin="0" Grid.Row="1" FontSize="16"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding StringProp3}" VerticalAlignment="Top" Grid.Column="1" Margin="0" FontSize="16"/>
<CheckBox Content="Is Bool True?" HorizontalAlignment="Left" IsChecked="{Binding BoolProp}" VerticalAlignment="Top" Grid.Column="1" Margin="0" Grid.Row="1" FontSize="16"/>
</Grid>
</Border>
</DataTemplate>
Таким образом, когда кто-то щелкает по флажку, он меняет значение объекта под ним, и поскольку элемент списка представляет ViewModel, если вы хотите что-то изменить в ListBoxItem, привязайте его к свойству в ViewModel и измените это свойство. ,
Например, допустим, вы хотите изменить цвет ListBoxItem на случайный цвет, когда пользователь устанавливает флажок (и по какой-либо причине вы не хотите использовать триггер или что-то подобное. Вы можете создать свойство на MyClassViewModel типа Brush и Datab привязывают к нему Border.Background и свойство Boolean, которое устанавливает для свойства MyClass то же значение. В установщике для логического свойства вы проверяете значение и, если оно истинно, задаете значение кисти (генератор случайных кистей не входит).
Таким образом, ViewModel сообщает представлению, как отображать данные в модели, и может перехватывать диапазоны данных из представления и при необходимости что-то делать с этим.
<DataTemplate DataType="{x:Type local:MyClassViewModel}">
<Border BorderBrush="#FF036200" BorderThickness="1" Background="{Binding BorderBackground}" CornerRadius="10">
Ответ на комментарий
У каждого человека есть свой способ работы с MVVM. У меня есть несколько видов ViewModels, которые я использую. Некоторые из них на самом деле являются моделями представления формы (используются для управления работой формы), моделями представления модели (используются для представления представлению [обычно пользовательскому контролю для редактирования деталей или элементу данных ItemsControl], как отображать данные). В моделях представления формы я иногда разбиваю их на NavigationViewModel и ViewModels для ведения записей в зависимости от ситуации.
В этом случае у меня действительно есть ViewModel для управления формой и Viewmodel для отображения данных. Модель представления формы часто обрабатывает команды кнопок для добавления или удаления элементов в коллекции или указания логики, которая сообщает представлению, включена ли кнопка сохранения или другое действие.
INotifyPropertyChanged
Очень легкий класс ViewModelBase, реализующий INPC
Imports System.ComponentModel
Public MustInherit Class ViewModelBase
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
End Class
А в ViewModels, которые наследуют:
Public Property IsSelected() As Boolean
Get
Return m_IsSelected
End Get
Set(ByVal value As Boolean)
m_IsSelected = value
OnPropertyChanged("IsSelected")
End Set
End Property