c# - 如何在 ListView 中从 ViewModel 调用命令,其中 ItemsSource 是其他模型类

标签 c# wpf xaml mvvm

所以我得到了一个 View ,其中一个 View 有一个listView。这个ListView有一个ItemSource“Persons”,这个 ListView 有一些CheckBox。

当选中复选框时,我想从我的 View 模型“RaceSimulatorViewModel”执行命令“CanStartRaceCheckCommand”。

但这不起作用,因为程序尝试从我的 Person 类获取命令。

所以存在一些绑定(bind)错误。

你能帮我吗?

我尝试过这个解决方案: WPF MVVM: EventTrigger is not working inside CheckBox

有 Xaml:

<ListView ItemsSource="{Binding Persons}" Grid.Row="1" Margin="40,100,367,46" Grid.RowSpan="3" Grid.ColumnSpan="2"  >
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Full Name"  DisplayMemberBinding="{Binding Path=Name}"/>
            <GridViewColumn Header="Participe to race" >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <!--<CheckBox IsChecked="{Binding Path=IsParticipateToRace}" Command="{Binding CanStartRaceCheckCommand, RelativeSource={RelativeSource AncestorType={x:Type vm:RaceSimulatorViewModel}, AncestorLevel=1}}"></CheckBox>-->
                        <!--<CheckBox Command="{Binding CanStartRaceCheckCommand}" CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}" />-->
                        <CheckBox IsChecked="{Binding Path=IsParticipateToRace}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

这是我的输出:

System.Windows.Data Error: 40 : BindingExpression path error: 'CanStartRAceCheckCommand' property not found on 'object' ''Person' (HashCode=43304686)'. BindingExpression:Path=CanStartRAceCheckCommand; DataItem='Person' (HashCode=43304686); target element is 'CheckBox' (Name=''); target property is 'Command' (type 'ICommand')

最佳答案

标记扩展 ' RelativeSource ' 用于绑定(bind)到 DataContext 外部的对象。与“StaticResource”扩展相反,它适用于“RelativeSource”Binding 属性而不是“Source”属性。它可用于遍历视觉树。请记住,您正在创建一棵元素树。 “RelativeSource”允许您遍历此树回到根元素,并通过传递目标元素的类型和相对树级别选择一个访问过的元素作为绑定(bind)源。这类似于在 Binding 对象上设置“Source”属性,您可以在其中指定数据源。数据本身或该源上数据的路径由Binding 的“Path”属性设置。

您必须遍历树,直到找到公开正确数据的元素。在您的情况下,绑定(bind)所需的数据源是 ListView (它位于默认数据上下文之外 --> 相对源)。 ListView通过“DataContext”公开数据RaceSimulatorViewModel

所以

Command="{Binding DataContext.CanStartRaceCheckCommand, RelativeSource={RelativeSource AncestorType={x:Type vm:RaceSimulatorViewModel}, AncestorLevel=1}}"

变成了

Command="{Binding DataContext.CanStartRaceCheckCommand, RelativeSource={RelativeSource AncestorType=ListView}}"

一般来说,数据上下文是由子元素继承的。对于模板(ControlTemplateDataTemplate),这略有不同。正如模板名称所示,ControlTemplate 用于描述控件,DataTemplate 用于描述数据(或如何可视化)。因此,ControlTemplate 的数据上下文是模板化控件,而 DataTemplate 的数据上下文是模板化数据(在您的情况下,Person 数据目的)。这使得基于数据状态的视觉效果成为可能,例如'Person.Age' < 18 --> 将其绘制为红色。相比之下,ControlTemplate 基本上基于控件状态,例如CheckBox.IsChecked? --> 更改其他一些控件的可见性。

关于c# - 如何在 ListView 中从 ViewModel 调用命令,其中 ItemsSource 是其他模型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53926027/

相关文章:

c# - 样式中的 GridViewColumn 标题绑定(bind)失败

c# - 向 WebBrowser 控件添加边框

.net - 更改wpf中的按钮边框厚度?

WPF:在数据绑定(bind)中使用表达式来评估 true/false

c# - 如何创建 word 文档对象的克隆?

c# - 带有附加属性的疑问

c# - DataGrid SortDirection 被忽略

wpf - 绑定(bind)到 WPF ToggleButton 的 IsChecked 状态

wpf - 如何阻止属性值沿着 xaml 中的元素树向下流动?

c# - 无法访问关闭的流异常