我有这个 ListView
:
<Window.DataContext>
<vm:PersonPickListViewModel />
</Window.DataContext>
....
<ListView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding PeopleOptions}" IsEnabled="{Binding ListEnabled}" SelectionMode="Multiple" >
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<CheckBox DataContext="{Binding ElementName=PersPickList, Path=DataContext}" IsChecked="{Binding AllSelected}" Command="{Binding ToggleSelectAll}" CommandParameter="{Binding ElementName=PersPickList, Path=DataContext}" />
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding GivenName}" />
</GridView>
</ListView.View>
</ListView>
header 模板复选框的 DataContext
是专门设置为整个 View 模型,PersonPickListViewModel
,因为 AllSelected
是该模式的属性,而不是列表项对象的属性,即 PeopleOptions
的成员,即 PickListPerson
。
由于 PickListPerson.IsSelected
绑定(bind)在单元格模板内,我猜它会采用其行的数据上下文,而不是其标题的数据上下文。当我在 Binding
后键入“Path”时,我得到了所有 PersonPickListViewModel
属性的列表,而不是所需的 PickListPerson
属性。
请问我做错了什么,我该如何解决?
最佳答案
我认为您的问题是无效的,因为您是在错误的假设下进行操作,即有问题的 CheckBox
未绑定(bind)到行项目,而实际上它是 .我认为您被 XAML 设计器误导了,建议在定义绑定(bind)时使用主视图模型的成员而不是项目 View 模型。设计器不是一个完美的工具,它只是试图猜测运行时的数据上下文是什么,但它经常会出错 - 就像你的情况一样。
如果我没记错的话,它假定数据上下文将被继承,因为它源于 XAML 结构:
CheckBox ← GridViewColumn ← GridView ← ListView ← ... ← Window
但在运行时,GridViewColumn.CellTemplate
数据模板被用作ContentPresenter.ContentTemplate
,ContentPresenter.Content
是行项. ContentPresenter
是 GridViewRowPresenter
的子项,它代表一个单元格。所以在运行时,模板化数据实际上是您的项目 View 模型。
关于c# - 为什么这个 ListView CheckBox 绑定(bind)到整个 View 模型而不是行项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40701347/