我知道我真的应该开始阅读一本关于XAML和WPF的书,因为我认为我的所有问题都属于对数据绑定的不了解(我多年来一直使用WinForms):
我的应用程序由TreeView和DataGrid组成。
在TreeView中,我为每个ParentNode添加了ViewModels,ChildNode为GrandChildNode。
我使用了Josh Smith found here的样本。
简而言之,他/我使用
<HierarchicalDataTemplate
DataType="{x:Type local:ViewModel.TreeViewChildNodeViewModel}"
ItemsSource="{Binding Children}">
</HierarchicalDataTemplate.Resources>
将ChildNode绑定到ChildNodeViewModel和相应的Model。
我添加 - 在TreeViewChildNodeViewModel构造函数中:
ContextMenuItems = new List<MenuItem>();
ContextMenuItems.Add(new MenuItem() {
Header = "Click",
Command = _cmdDoSmth
ToolTip = new ToolTip() { Content = "blabla" }
}
);
使用此属性向View公开:
private readonly List<MenuItem> ContextMenuItems;
public List<MenuItem> ContextMenu {
get { return ContextMenuItems; }
}
请注意,我有多个构造函数。我将不同的ContextMenuItem添加到ContextMenu列表,具体取决于我希望ViewModel使用的模型。 “root”ChildNode由a:
组成<TextBlock
Text="{Binding ChildNodeDisplayItem}">
<TextBlock.ContextMenu>
<ContextMenu
ItemsSource="{Binding ContextMenu}"></ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
这应该是这样的。现在我的问题开始于尝试与datagrid做类似的事情。
我需要做的是:
我想在datagrid中显示行。每一行都有自己的Viewmodel,它有一个暴露的ContextMenuItem列表(当然还有模型)。我希望能够根据所选的视图模型定义每个上下文菜单的计数,标题和命令。
到目前为止我做了什么:
在我的MainWindow.xaml:
<Controls:MetroWindow.Resources>
<ContextMenu x:Key="DataRowContextMenu" ItemsSource="{Binding Path=ActionReactionDataGridViewModel/ContextMenu, RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}}"/>
</Controls:MetroWindow.Resources>
<DataGrid
AutoGenerateColumns="True"
AutoGeneratingColumn="OnAutoGeneratingColumn"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="1,1,1,1"
Margin="0,0,0,0"
ItemsSource="{Binding Path=ActionReactionDataGridViewModel/DataGridSource}"
SelectedItem="{Binding Path=ActionReactionDataGridViewModel/SelectedDataGridItem}"
BorderBrush="#FF020202">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" /> </Style>
<DataGrid.RowStyle>
</DataGrid>
在我的MainWindowViewModel中:
public MainWindowViewModel() // Constructor
{
actionReactionDataGrid = new ObservableCollection<ActionReactionDataGridViewModel>();
actionReactionDataGrid.Add(new ActionReactionDataGridViewModel());
}
private ObservableCollection<ActionReactionDataGridViewModel> actionReactionDataGrid;
public ObservableCollection<ActionReactionDataGridViewModel> ActionReactionDataGridViewModel
{
get { return actionReactionDataGrid; }
}
我的ActionReactionDataGridViewModel在这里:
public class ActionReactionDataGridViewModel : ViewModelBase
{
private readonly List<MenuItem> ContextMenuItems;
public ActionReactionDataGridViewModel()
{
ContextMenuItems = new List<MenuItem>();
ContextMenuItems.Add(new MenuItem()
{
Header = "blubb"
});
dataGridSource = new ObservableCollection<ActionReactionDataGridModel>();
dataGridSource.Add(new ActionReactionDataGridModel("Status","Eventname","Eventtyp","ReaktionName","ReaktionTyp"));
}
public List<MenuItem> ContextMenu {
get { return ContextMenuItems; }
}
private ActionReactionDataGridModel selectedDataGridItem;
public ActionReactionDataGridModel SelectedDataGridItem {
get { return selectedDataGridItem; }
set {selectedDataGridItem = value; RaisePropertyChanged("SelectedDataGridItem"); }
}
private ObservableCollection<ActionReactionDataGridModel> dataGridSource;
public ObservableCollection<ActionReactionDataGridModel> DataGridSource {
get { return dataGridSource; }
set { dataGridSource = value; RaisePropertyChanged("DataGridSource"); }
}
}
我认为发布模型的内容不是必需的,因为它只包含列标题和一些示例字符串。我认为我缺少的是告诉MainWindow.xaml中的View中的DataGrid控件将itemssource绑定到“DataGridSource”而不是“ActionReactionDataGridViewModel”。
我在SO上发现了关于将Context Menus添加到datagridrow的其他帖子。我缺少的是能够将计数,文本和命令绑定到每个视图模型。
非常感谢任何帮助。
谢谢。
//编辑1
确定。找出如何从viewmodel集合中传递viewmodel的属性很容易。
我添加了
ItemsSource="{Binding Path=ActionReactionDataGridViewModel/DataGridSource}
解释是here
现在我“只是”需要弄清楚如何将contextmenu项添加到每个viewmodel ......
答案 0 :(得分:0)
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="HeaderName">
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
在内部菜单项中,您可以编写控件。