Как найти нужный элемент из списка, привязанного к CollectionViewSource - PullRequest
1 голос
/ 08 сентября 2011

У меня есть ListBox с его ItemsSource, связанным с CollectionViewSource, который связан с ObservableCollection.

Шаблон для ListBoxItem включает CheckBox , который при проверке указывает, что элемент выбран.

Моя проблема в том, что я понятия не имею, как выяснить, на каких пунктах нажата их галочка.

1 Ответ

1 голос
/ 08 сентября 2011

С какими флажками связаны? Если он привязан к свойству объектов в вашей коллекции, вам не нужно выяснять, какой флажок был выбран. Если он не привязан к чему-либо на объекте или в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...