Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从绑定到CollectionViewSource的列表框中找到正确的项_C#_Wpf_Mvvm_Listbox - Fatal编程技术网

C# 如何从绑定到CollectionViewSource的列表框中找到正确的项

C# 如何从绑定到CollectionViewSource的列表框中找到正确的项,c#,wpf,mvvm,listbox,C#,Wpf,Mvvm,Listbox,我有一个列表框,其ItemsSource绑定到CollectionViewSource,后者绑定到ObservableCollection ListBoxItem的模板包含一个复选框,选中该复选框时,表示该项目已被选中 我的问题是,我不知道如何找出哪些项目的复选框被单击。复选框绑定到什么?如果它绑定到集合中对象的属性,则不需要确定单击了哪个复选框。如果未绑定到对象或ViewModel上的某个对象,则可以从列表框中获取SelectedItem 之前,我已将listBox的SelectedItem属

我有一个
列表框
,其ItemsSource绑定到CollectionViewSource,后者绑定到ObservableCollection

ListBoxItem的模板包含一个复选框,选中该复选框时,表示该项目已被选中


我的问题是,我不知道如何找出哪些项目的复选框被单击。

复选框绑定到什么?如果它绑定到集合中对象的属性,则不需要确定单击了哪个复选框。如果未绑定到对象或ViewModel上的某个对象,则可以从列表框中获取SelectedItem

之前,我已将listBox的SelectedItem属性绑定到ViewModel上的一个属性,以便在它发生更改时运行它

至于获取索引,您应该能够将从列表框返回的idex与CollectionViewSource.View中某个项目的索引相匹配,该视图按显示顺序包含集合的当前视图

如果您不使用MVVM,我建议您使用它。我一开始没有使用它,很快就陷入了代码落后的困境

MVVM中的示例 假设我们有一个MyClass,它有三个字符串属性和一个布尔值。在MVVM中,我们有一个MyClassViewModel,它有一个属性来包含MyClass的实例以及视图所需的任何功能(本例中是listboxitem)。我们还有一个MyWindowViewModel,它将为我们的主视图保存数据集合和其他内容

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>
当我们获得数据时,我们将其放入(MyClassViewModel的)ObservableCollection中。我通常在数据检索后台工作人员的WorkCompleted处理程序中执行此操作

   For Each mc as MyClass in e.Results
      MyClassCollection.Add(New MyClassViewModel(mc)
   Next
listbox仍将通过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>
在继承的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

复选框绑定到什么?如果它绑定到集合中对象的属性,则不需要确定单击了哪个复选框。如果未绑定到对象或ViewModel上的某个对象,则可以从列表框中获取SelectedItem

之前,我已将listBox的SelectedItem属性绑定到ViewModel上的一个属性,以便在它发生更改时运行它

至于获取索引,您应该能够将从列表框返回的idex与CollectionViewSource.View中某个项目的索引相匹配,该视图按显示顺序包含集合的当前视图

如果您不使用MVVM,我建议您使用它。我一开始没有使用它,很快就陷入了代码落后的困境

MVVM中的示例 假设我们有一个MyClass,它有三个字符串属性和一个布尔值。在MVVM中,我们有一个MyClassViewModel,它有一个属性来包含MyClass的实例以及视图所需的任何功能(本例中是listboxitem)。我们还有一个MyWindowViewModel,它将为我们的主视图保存数据集合和其他内容

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>
当我们获得数据时,我们将其放入(MyClassViewModel的)ObservableCollection中。我通常在数据检索后台工作人员的WorkCompleted处理程序中执行此操作

   For Each mc as MyClass in e.Results
      MyClassCollection.Add(New MyClassViewModel(mc)
   Next
listbox仍将通过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>
在继承的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

这可能会有帮助:这看起来不错,但似乎对我不起作用。我将此代码添加到我的代码隐藏文件中:EventManager.RegisterClassHandler(typeof(SurfaceListBoxItem)、SurfaceListBoxItem.MouseLeftButtonDownEvent、new RoutedEventHandler(this.OnMouseLeftButtonDown));private void OnMouseLeftButtonDown(对象发送方,RoutedEventTargets e){MessageBox.Show(“鼠标按下”);}但事件从未触发:(我找到了一个解决方法:在Listbox的ItemContainerStyle中,我添加了此事件的sender对象是我单击的ListboxItem。现在我可以从ListboxItem.content属性获取源对象,因此我知道必须更改数据集中的哪个项。在我的oppinion中,这是一个可怕的解决方案,但它现在可以工作。如果有人现在,如何正确操作,请让我知道这可能会有所帮助:看起来不错,但似乎对我不起作用。我将此代码添加到我的代码隐藏文件中:EventManager.RegisterClassHandler(typeof(SurfaceListBoxItem)、SurfaceListBoxItem.MouseLeftButtonDownEvent、new RoutedEventHandler(this.OnMouseLeftButtonDown));private void OnMouseLeftButtonDown(对象发送方,RoutedEventTargets e){MessageBox.Show(“鼠标按下”);}但事件从未被触发:(我找到了一个解决方法:在Listbox的ItemContainerStyle中,我添加了此事件的sender对象是我单击的ListboxItem。现在我可以从ListboxItem.content属性获取源对象,因此我知道必须更改数据集中的哪个项。在我的oppinion中,这是一个可怕的解决方案,但它现在可以工作。如果有人现在,如何正确操作,请让我知道Hi CodeWarrior,谢谢你的帖子。正如我提到的,我很遗憾不能使用listbox的SelectedItem属性,因为单击复选框不会自动选择父ListboxItem。我现在将checkbox标记属性绑定到我的Datasourceobject中的字符串值。有了它,我可以现在,哪一项已经改变了。mvvm会有更优雅的方式吗?请参阅我的帖子以获取一些示例。如果您有一些特定的功能,请告诉我,我可以给您一个示例,说明我将如何在mvvm模式下实现它。这就是我所说的一个很好的答案。谢谢。我将其标记为答案,因为它对我有帮助。唯一的事情是我想知道的是,为什么我必须