关于WPF DataGridColumn中的ContextMenu,我有一个棘手的问题。我不知道是否有人已经面临这个问题,但如果有人能帮助我,我将非常感激!
让我们从我的课程开始
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
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;
}}这是我的视图及其背后的代码
<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();
}
}我在这个例子中想要的是在DataGridColumn中有一个动态的ContextMenu。首先,我在整个DataGrid中放置了一个ContextMenu,它工作得很好。但是在我的例子中,我只需要在单元格中右键单击一个ContextMenu,而不是在整个DataGrid中。因此,我尝试使用具有ContextMenu的TextBox来编辑DataGridColumn的DataTemplate。不幸的是,当我在TextBox中右键单击时,它的ContextMenu的ItemsSource似乎为空。但是,当我在TextBox中的DataGrid外部右键单击时,D21的D22被正确绑定。
我想这可能是DataContext的问题,因为ContextMenu和DataGrid没有相同的视觉树,所以我在ContextMenu的ItemsSource绑定中添加了RelativeSource,但没有结果!
有什么想法吗?
发布于 2011-01-20 17:39:10
首先,感谢Rick在这个问题上抽出时间指导我。
我已经在msdn论坛上发布了这个问题,我有一个解决它的答案
<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>
我想要做的是通过TextBox的标记将用户控件的DataContext传递给theContextMenu
对于那些想让它在我的代码中正常工作的人,你需要将UserControlRessoucre定义为:
<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论坛链接:-->here<--
非常感谢谢尔顿·肖的回答
发布于 2011-01-18 08:59:07
你在正确的轨道上。您确实需要使用RelativeSource,但使用Self,然后使用PlacementTarget将视觉树交换到TextBox,您可以从中获得其DataContext,该use应该是从DataGridCell继承的,并且最终能够到达您的menu属性。
我所指的未经测试的例子:
<ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext.listDataMenu}"/>发布于 2011-01-19 18:57:33
尽管我在Datagrid中的每一行都需要相同的contextMenu,但我尝试了您的建议,但无法使其工作:(可能是我忘记了什么
听说我是这样修改我的类的:
public class Person
{
public string Type { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
public Column Column { get; set; }
}
public class Menu
{
public string Name { get; set; }
public int Code { get; set; }
public ObservableCollection<Menu> listMenu { get; set; }
}
public class Column
{
public ObservableCollection<Menu> listDatatMenu { get; set; }
}然后,我在ViewModel中更改InitData函数,如下所示:
private void InitData()
{
listDataPersons = new List<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 });
DataPersons[0].Column = new Column();
DataPersons[0].Column.listDatatMenu = DataMenu;
DataPersons[1].Column = new Column();
DataPersons[1].Column.listDatatMenu = DataMenu;
listDataPersons = DataPersons;
listDataMenu = DataMenu;
}最后是我视图中的ContextMenu
<ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext.Column.listDataMenu}"/> 如果我犯了一个新手错误,我很抱歉,但它确实起作用了
https://stackoverflow.com/questions/4711802
复制相似问题