如何在MVVM中的WPF DataGridColumn中添加ContextMenu? [英] How to add a ContextMenu in the WPF DataGridColumn in MVVM?

查看:196
本文介绍了如何在MVVM中的WPF DataGridColumn中添加ContextMenu?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WPF DataGridColumn 中的 ContextMenu 有一个棘手的问题。我不知道有人是否已经面对这个问题,但是如果有人可以帮助我,我将非常感激!

I've got a tricky issue regarding ContextMenu in a WPF DataGridColumn. I don't know if someone have already face this issue but I will really appreciate if someone can help me!

让我们开始我的课程

public class Person
{
    public string Type { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }
}

public class Menu
{
    public string Name { get; set; }
    public int Code { get; set; }
    public ObservableCollection<Menu> listMenu { get; set; }
}

现在我的ViewModel

Now my ViewModel

 public class MyViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Person> DataPersons = new ObservableCollection<Person>();
    private ObservableCollection<Menu> DataMenu = new ObservableCollection<Menu>();

    public ObservableCollection<Person> listDataPersons { get; set; }
    public ObservableCollection<Menu> listDataMenu { get; set; }

    public MyViewModel()
    {
        //initialization
        InitData();
    }

    private void InitData()
    {
        listDataPersons = new ObservableCollection<Person>();
        listDataMenu = new ObservableCollection<Menu>();

        DataPersons.Add(new Person() { Type = "Friend", Name = "Doe", Surname = "John", Age = 42});
        DataPersons.Add(new Person() { Type = "Friend", Name = "Smith", Surname = "Jack", Age = 42});

        DataMenu.Add(new Menu() { Name = "Principal", Code = 1});
        DataMenu.Add(new Menu() { Name = "Secondary", Code = 2});
        DataMenu.Add(new Menu() { Name = "Associated", Code = 3});

        DataMenu[2].listMenu = new ObservableCollection<Menu>();
        DataMenu[2].listMenu.Add(new Menu() { Name = "Associated 1", Code = 31 });

        listDataPersons = DataPersons;
        listDataMenu = DataMenu;
    }}

这是我的视图,它的代码在

Here are my View and it's code behind

<DataGrid ItemsSource="{Binding listDataPersons}" AutoGenerateColumns="False">
    <DataGrid.ContextMenu>
        <ContextMenu ItemsSource="{Binding listDataMenu}"/>
    </DataGrid.ContextMenu>
    <DataGrid.Columns>                
        <DataGridTemplateColumn IsReadOnly="True" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Width="80" >
                    <TextBlock.ContextMenu>
                        <ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}, Path=DataContext.listDataMenu}"/>
                    </TextBlock.ContextMenu>
                    </TextBlock>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

代码背后

public partial class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent();

        this.DataContext = new MyViewModel();
    }
}

在这个例子中我想要的是有一个动态 ContextMenu DataGridColumn 中。首先,我在整个 DataGrid 中放置一个 ContextMenu ,它的工作正常。但是在我的情况下,我只需要在单元格中右键单击 ContextMenu ,而不是整个 DataGrid 中。所以我试图用 TextBox DataGridColumn DataTemplate >其中有一个 ContextMenu 。不幸的是,当我右键单击 TextBox 它的 ContextMenu ItemsSource 似乎是空的。但是当我右键单击 DataGrid TextBox 之前, DataGrid ContextMenu 正确绑定。

What I wanted in this example is to have a dynamic ContextMenu in DataGridColumn. First I put a ContextMenu in the entire DataGrid and it works fine. But in my case I need a ContextMenu only on a right click in Cells not in the entire DataGrid. So I tried to edit DataGridColumn's DataTemplate with a TextBox which has a ContextMenu. Unfortunately when I right click in the TextBox it's ContextMenu's ItemsSource seem to be empty. However when I right click outside the TextBox in the DataGrid, the DataGrid's ContextMenu is correctly binded.

我在想这可能是一个 DataContext 因为 ContextMenu DataGrid 没有相同的Visual Tree我在 ContextMenu ItemsSource 绑定中添加了 RelativeSource 没有结果!!!

I was thinking that it might be a problem of DataContext because ContextMenu and DataGrid do not have the same Visual Tree so I added RelativeSource in the ContextMenu's ItemsSource binding but no result!!!

任何想法?

推荐答案

所有感谢Rick花时间指导我这个问题。

First of all thank Rick for taking time to guide me on this issue.

我在msdn论坛中发布了这个问题,我有一个解决方案的答案

I'd posted the problem in msdn Forum and I had an answer to solve it

<TextBlock Text="{Binding Name}" Width="80" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}, Path=DataContext}">
<TextBlock.ContextMenu>                                                                                                
    <ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag.listDataMenu}" ItemContainerStyle="{StaticResource ContextMenuItemStyle}"/>
</TextBlock.ContextMenu>                                

想想做的是传递UserControl的DataContext通过TextBox的标签toContextMenu

The think to do is passing the UserControl's DataContext to theContextMenu through the TextBox's Tag

对于那些希望通过我的代码正常工作的人,您需要将UserControlRessoucre定义为:

For those who want to make it work properly with my code you'll need to define UserControlRessoucre as :

<UserControl.Resources>
    <HierarchicalDataTemplate DataType="{x:Type cmd:Menu}" ItemsSource="{Binding listMenu}">
        <TextBlock Text="{Binding Path=Name}"/>            
    </HierarchicalDataTemplate>

    <Style x:Key="ContextMenuItemStyle">
        <Setter Property="MenuItem.ItemsSource" Value="{Binding Path=listMenu}"/>             
    </Style>
</UserControl.Resources>

这是原始答案的msdn论坛链接: - >这里< -

this is the msdn forum link of the original answer: -->here<--

很多谢谢谢尔德这个答案

many thanks Sheldon Xiao for this answer

这篇关于如何在MVVM中的WPF DataGridColumn中添加ContextMenu?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆