如何从ContextMenu绑定到MVVM中的WPF DataGridColumn? [英] How to bind to WPF DataGridColumn in MVVM from ContextMenu?
问题描述
XAML:
< DataGrid资源>
< ContextMenu x:Key =DataGridColumnHeaderMenu>
< MenuItem Name =mi_groupHeader =分组
Command ={Binding RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type local:MainWindow}},Path = DataContext.GroupColumn}
CommandParameter ={Binding Path = Column.SortMemberPath,RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = DataGridColumnHeader}}>
< / MenuItem>< / ContextMenu>
< Style TargetType ={x:Type DataGridColumnHeader}>
< Setter Property =ContextMenuValue ={StaticResource DataGridColumnHeaderMenu}/>
< / Style>
< /DataGrid.Resources>
ViewModel:
code> public ICommand GroupColumn
{
get
{
if(groupColumn == null)
{
groupColumn = new RelayCommand((param )=> {
UngroupColumns.Execute(null);
string groupPropertyName = param as string; ///不要此Switch。ViewModel不知道标题名称
switch(groupPropertyName)
{
caseProject:{groupPropertyName =project_id; break;}
caseDate:{groupPropertyName =date ; break;}
casePerson:{groupPropertyName =person_id; break;}
default:{groupPropertyName = null; break;}
}
if(groupPropertyName!= null)
{
MyData.GroupDescriptions.Add(new PropertyGroupDescription(groupPropertyName));
MyData.SortDescriptions.Add(new SortDescription(groupPropertyName,ListSortDirection.Ascending));
}
});
}
return groupColumn;
}
}
我终于找到了解决问题的方法 here 。
但是我仍然不明白为什么CommandParameters在我尝试使用时不会更新:
CommandParameter ={ Binding RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type DataGridColumnHeader}},Path = Column.SortMemberPath}
所以这里是适用于我的代码:
< DataGrid.Resources>
< ContextMenu x:Key =DataGridColumnHeaderMenu>
< MenuItem Name =mi_groupHeader =Make Groups
Command ={Binding RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type local:MainWindow}},Path = DataContext.GroupColumn }
CommandParameter ={Binding RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type ContextMenu}},Path = PlacementTarget.Column.SortMemberPath}>
< MenuItem.Icon>
< Image Source =images / Treeview.png/>
< /MenuItem.Icon>
< / MenuItem>
< / ContextMenu>
< Style TargetType ={x:Type DataGridColumnHeader}>
< Setter Property =ContextMenuValue ={StaticResource DataGridColumnHeaderMenu}/>
< / Style>< /DataGrid.Resources>
在我的情况下使用SortMemberPath的优点是我还可以检索DataGridComboxColumn的值(SelectedValuePath) 。假设SelectedValuePath等于SortMemberPath,这在我的情况下。
ViewModel:
private RelayCommand groupColumn;
public ICommand GroupColumn
{
get
{
if(groupColumn == null)
groupColumn = new RelayCommand(
(param)= >
{
UngroupColumns.Execute(null);
// param包含DataGridColumn的SortMemberPath
string groupPropertyName = param as string;
if(groupPropertyName!= null)
{
MyData.GroupDescriptions.Add(new PropertyGroupDescription(groupPropertyName));
MyData.SortDescriptions.Add(new SortDescription(groupPropertyName,ListSortDirection.Ascending ));
}
});
return groupColumn;
}
}
I have a DataGrid with different Columns (TextBox, Combobox, DataPicker, etc.) displaying Data via MVVM. Now I want to have ContextMenu on each ColumnHeader to Group by the selected column, but I can't access the Binding Source (Binding Path) of the Column to tell ViewModell which column it has to Group. When I open the context menu for the first time it works fine, but when I open the context menu once again, it still passes the SortMemberPath from the first time. What am I doing wrong?
XAML:
<DataGrid.Resources>
<ContextMenu x:Key="DataGridColumnHeaderMenu">
<MenuItem Name="mi_group" Header="Grouping"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, Path=DataContext.GroupColumn}"
CommandParameter="{Binding Path=Column.SortMemberPath, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridColumnHeader}}">
</MenuItem></ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContextMenu" Value="{StaticResource DataGridColumnHeaderMenu}" />
</Style>
</DataGrid.Resources>
ViewModel:
public ICommand GroupColumn
{
get
{
if (groupColumn == null)
{
groupColumn = new RelayCommand( (param) => {
UngroupColumns.Execute(null);
string groupPropertyName = param as string; ///Don't want this Switch. ViewModel doesn't know name of the header
switch (groupPropertyName)
{
case "Project": {groupPropertyName = "project_id"; break;}
case "Date": {groupPropertyName = "date"; break;}
case "Person": {groupPropertyName = "person_id"; break;}
default: {groupPropertyName = null; break; }
}
if (groupPropertyName != null)
{
MyData.GroupDescriptions.Add(new PropertyGroupDescription(groupPropertyName));
MyData.SortDescriptions.Add(new SortDescription(groupPropertyName, ListSortDirection.Ascending));
}
});
}
return groupColumn;
}
}
So I've finally found a solution to my problem here. But I still don't understand why CommandParameters is not updating when I try to use:
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridColumnHeader}}, Path=Column.SortMemberPath}"
So here is the code that works for me:
<DataGrid.Resources>
<ContextMenu x:Key="DataGridColumnHeaderMenu">
<MenuItem Name="mi_group" Header="Make Groups"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, Path=DataContext.GroupColumn}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Column.SortMemberPath}">
<MenuItem.Icon>
<Image Source="images/Treeview.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContextMenu" Value="{StaticResource DataGridColumnHeaderMenu}" />
</Style></DataGrid.Resources>
The Advantage of using SortMemberPath in my case was that I could retrieve also a value (SelectedValuePath) for DataGridComboxColumn. Assumed that SelectedValuePath is equal to SortMemberPath which is in my case.
ViewModel:
private RelayCommand groupColumn;
public ICommand GroupColumn
{
get
{
if (groupColumn == null)
groupColumn = new RelayCommand(
(param) =>
{
UngroupColumns.Execute(null);
// param contains SortMemberPath of the DataGridColumn
string groupPropertyName = param as string;
if (groupPropertyName != null)
{
MyData.GroupDescriptions.Add(new PropertyGroupDescription(groupPropertyName));
MyData.SortDescriptions.Add(new SortDescription(groupPropertyName, ListSortDirection.Ascending));
}
});
return groupColumn;
}
}
这篇关于如何从ContextMenu绑定到MVVM中的WPF DataGridColumn?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!