1

我有一个数据网格列,如下所示:

<toolkit:DataGridTemplateColumn>
                        <toolkit:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=LabelName}" Background="{Binding Path=Color}">
                                    <TextBlock.ContextMenu>
                                        <ContextMenu>
                                            <MenuItem x:Name="Assign" Header="Assign"
                                                      mvvm:CommandBehavior.Event="Click"
                                                      mvvm:CommandBehavior.Command="{Binding Path=DataContext.EditLabelCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}, AncestorLevel='1'}}"
                                                      mvvm:CommandBehavior.CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=DataContext}"/>
                                        </ContextMenu>
                                    </TextBlock.ContextMenu>
                                </TextBlock>
                            </DataTemplate>
                        </toolkit:DataGridTemplateColumn.CellTemplate>

我正在尝试访问 DataContext 的 EditLabelCommand,但找不到绑定源。我应该怎么做才能访问我的 DataContext 的命令?

4

1 回答 1

3

当您 a) 将 DataContext 绑定到其他东西时,DataContext 会随着您向下移动可视化树而发生变化,或者 b) 使用类似项目控件(或在您的情况下为网格)之类的东西,它在集合中的每个项目重复您的数据模板一次,为每个项目设置数据上下文。

在您的示例中,您的菜单项与您的 TextBlock 具有相同的 DataContext。这将是绑定到数据网格每一行的对象。

根据您的代码,我认为您在整个 UserControl 的 DataContext 集中有一个可用的 EditLabelCommand。这可能是您绑定到网格的集合的父级。(如果这些假设有任何错误,请纠正我。)

如果是这种情况,您可以做几件事:

  • 您可以继续使用相对绑定。如您所见,这很复杂且容易出错,并且不会导致数据模板或其他 XAML 的良好重用。我建议你避免使用这种技术。

  • 将命令保留在整个数据上下文中的一种更简单的方法是使用WPF Model-View-ViewModel Toolkit中的CommandReference。这允许您将命令作为资源引用并使用资源绑定来访问它。像这样:

    <用户控件.资源>
        <mvvmToolkit:CommandReference x:Key="EditLabelCommandReference" Command="{Binding EditLabelCommand}" />
    </UserControl.Resources>

    <!-- 你的命令绑定看起来更简单 -->
    mvvm:CommandBehavior.Command="{StaticResource EditLabelCommandReference}"
  • 另一种(可能更好的)技术是重构以对每一行使用 MVVM 模式。这样,您将在网格的每一行使用一个简单的 ViewModel。这允许每一行保持自己的状态。因为您可以将 Command 实现移动到此 ViewModel 中,所以每行都有一个命令,无需传递参数。这使得一次编辑多个行的标签成为可能。(如果这是一个要求。)
于 2009-09-04T15:47:28.517 回答