【问题标题】:ContextMenu Binding Source within a DataGrid using MVVM使用 MVVM 的 DataGrid 中的 ContextMenu 绑定源
【发布时间】:2009-09-03 15:33:25
【问题描述】:

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

<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 的命令?

【问题讨论】:

    标签: datagrid mvvm binding contextmenu


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-06
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      相关资源
      最近更新 更多