I have a following Xaml:
<DataGrid
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
SelectionMode="Single">
<DataGrid.ContextMenu>
<ContextMenu MinWidth="200">
<MenuItem
cal:Message.Attach="[Click] = [Action OnGroupSelected($data)]"
Header="Move Item to Group"
ItemsSource="{Binding Groups}">
<MenuItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" />
<DataGridTextColumn Binding="{Binding Description}" Header="Description" />
</DataGrid.Columns>
</DataGrid>
All I wanted to have a contextMenu appear when click on a DataGrid Item, it will show a List of available group that I want to move the Item to.
I can get the ContextMenu to show all the Group with their name and call the OnGroupSlected(Group SelectedGroup) but the SelectedGroup is null. How to pass the Item to OnGroupSlected correctly? I'm using Caliburn.Micro to handle the MVVM.
I have tried many approaches but none of them work:
<MenuItem
Header="Move Item to Group"
ItemsSource="{Binding Groups}">
<MenuItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</MenuItem.ItemTemplate>
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="cal:Message.Attach" Value="[Click] = [Action OnGroupSelected($data)]" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
I tried to solve your problem and ended up with this solution:
cal:Message.Attach="[Click] = [Action OnGroupSelected($eventArgs)]"
$data
which by default does not exists.And in your code you can access it like this:
public void OnGroupSelected(RoutedEventArgs args)
{
if (args.OriginalSource is FrameworkElement fe)
{
if (fe.DataContext is Group group)
{
MessageBox.Show(group.Name);
}
}
}
$data
in XAML, but in your code you need to specify (add it) it first:
...MessageBinder.SpecialValues.Add("$data", value =>
{
if (value.EventArgs is not RoutedEventArgs args)
return null;
if (args.OriginalSource is not FrameworkElement fe)
return null;
return fe.DataContext;
});
And in XAML use: cal:Message.Attach="[Click] = [Action OnGroupSelected($data)]"
And in code:
public void OnGroupSelected(Group SelectedGroup)
{
MessageBox.Show(SelectedGroup.Name);
}
Hopefully this will help you.