Hi,
try this another approach:
XAML:
<Window x:Class="WpfApp1.Window83"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp83"
mc:Ignorable="d"
Title="Window83" Height="450" Width="800">
<Window.Resources>
<local:ViewModel x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding MyModules}" AutoGenerateColumns="False">
<DataGrid.Resources>
<ContextMenu x:Key="RowMenu" ItemsSource="{Binding MenuNames}" >
<ContextMenu.ItemTemplate>
<DataTemplate>
<Grid Margin="2" >
<MenuItem Header="{Binding}"
Command="{Binding Source={StaticResource vm}}"
CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Module Name" Width="*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Module Description" Width="3*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.Description}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Label Grid.Row="1" Content="{Binding Info}"/>
</Grid>
</Window>
And classes:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace WpfApp83
{
public class ViewModel : ICommand, INotifyPropertyChanged
{
public ViewModel() => LoadData();
public CollectionViewSource cvs = new CollectionViewSource();
public ICollectionView MyModules { get => cvs.View; }
private void LoadData()
{
Random rnd = new Random();
ObservableCollection<Module> col = new ObservableCollection<Module>();
for (int i = 1; i < 10; i++)
{
Module m = new Module();
m.Configuration.Name = $"Name {i}";
m.Configuration.Description = $"Description {i}";
for (int k = 1; k < rnd.Next(3, 8); k++) m.MenuNames.Add($"Menu {k} (Name {i})");
col.Add(m);
}
cvs.Source = col;
}
public string Info { get; set; }
public void Execute(object parameter)
{
Info = parameter.ToString();
OnPropertyChanged(nameof(Info));
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
public class Module
{
public Config Configuration { get; set; } = new Config();
public List<string> MenuNames { get; set; } = new List<string>();
}
public class Config
{
public string Name { get; set; }
public string Description { get; set; }
}
}