【问题标题】:Setting DataGrid and ContextMenu with Same DataContext使用相同的 DataContext 设置 DataGrid 和 ContextMenu
【发布时间】:2015-07-27 13:59:55
【问题描述】:

我正在尝试为传入所选菜单项 (Mvvm) 的数据网格动态创建上下文菜单。我希望上下文菜单的 DataContext 与网格相同。

我有以下 Xaml

<Grid>
  <!-- Cut some other stuff -->
  <Border Grid.Row="2" BorderBrush="Black" BorderThickness="1">
    <DataGrid x:Name="MyDataGrid" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=GridData}" AutoGenerateColumns="False" IsReadOnly="True" GridLinesVisibility="None" SelectionUnit="Cell" SelectionMode="Single">
      <DataGrid.ContextMenu>
        <ContextMenu ItemsSource="{Binding ContextMenuActions}">
          <MenuItem Header="{Binding DisplayName}" Command="{Binding Command}" />
        </ContextMenu>
      </DataGrid.ContextMenu>
      <DataGrid.Columns>
        <DataGridTextColumn  Header="DataOne" Width="130" Binding="{Binding Path=DataOne}"/>
        <DataGridTextColumn  Header="DataTwo"   Width="100" Binding="{Binding Path=DataTwo}"/>
      <DataGrid.Columns>
      <DataGrid.InputBindings>
        <MouseBinding Gesture="RightClick"  Command="{Binding DataGridRightClick}" CommandParameter="{Binding ElementName=MyDataGrid, Path=SelectedCells}" />
      </DataGrid.InputBindings>
    </DataGrid>
  </Border>
</Grid> 

以及我用于数据网格并且还想用于我的上下文菜单的数据上下文的以下类(为了便于阅读,我已经删除了所有数据网格填充代码)和菜单项

public class DataViewModel : ViewModelBase // Implements INotifyPropertyChanged
{
    // All code that populates the grid has been removed

    public ObservableCollection<MenuItemViewModel> ContextMenuActions { get; set; }
    public ICommand DataGridRightClick { get; private set; }

    public MarketDataViewModel()
    {
        DataGridRightClick = new RelayCommand(RightClick);
    }

    public void RightClick(object obj)
    {
        MenuItemViewModel menuItem = new MenuItemViewModel("Test", new RelayCommand(TestCall));
        ContextMenuActions.Add(menuItem); // I ensure this is added on the gui thread
        MenuItemViewModel menuItem1 = new MenuItemViewModel("Test2", new RelayCommand(TestCall));
        ContextMenuActions.Add(menuItem1); // I ensure this is added on the gui thread but for 
    }

    private void TestCall(object obj)
    {
        // want to pass in the selected menuitem
    }
}

public class MenuItemViewModel 
{
    public MenuItemViewModel(string displayName,ICommand command)
    {
        DisplayName = displayName;
        Command = command;
    }

    public string DisplayName { get; set; }
    public ICommand Command { get; set; }
}

目前,当我单击数据网格时,右键单击事件会被调用并运行良好,但网格上会出现一个空的上下文菜单。

谢谢, 尼克

【问题讨论】:

  • 顺便说一下,您设置了两次ContextMenu 项目。您在 XAML 中的 MenuItem 可能会阻止 ItemsSource 绑定工作,因为您只能使用一种方法:Items 集合(您在 XAML 上设置)或 ItemsSource
  • 您是否尝试设置ItemTemplate,也许?
  • 是的,我确实尝试设置项目模板,但没有帮助。我该怎么做。我想我做了类似
  • 误按回车 ...结束标签。这是正确的吗?
  • 是的,没错。尝试这样做并按照@MikeEason 在他的回答中所说的那样做。我认为这可能是您需要的两件事的结合。

标签: wpf mvvm datagrid contextmenu datacontext


【解决方案1】:

您需要绑定到父DataGridDataContext.ContextMenuActions最简单的方法是使用以下绑定:

<ContextMenu ItemsSource="{Binding DataContext.ContextMenuActions, ElementName=MyDataGrid}" ... 

【讨论】:

  • 谢谢,但现在我得到 System.Windows.Data 警告:74:查找名称 MyDataGrid:查询的 ContextMenu (hash=13257961) System.Windows.Data 错误:4:无法找到绑定源'元素名称 = MyDataGrid'。 BindingExpression:Path=DataContext.ContextMenuActions;数据项=空;目标元素是'ContextMenu'(名称='');目标属性是“ItemsSource”(类型“IEnumerable”)。我尝试添加其他帖子中建议的 x:Reference ,但这也不起作用。任何想法为什么会这样?
猜你喜欢
  • 1970-01-01
  • 2014-09-21
  • 2011-07-29
  • 1970-01-01
  • 2010-12-19
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多