Caliburn框架中二级Menu无法调用ViewModel方法

公司WPF程序开发中应用了Caliburn框架,最近在做一个DataGrid上二级MenuItem时,发现Click方法无法调用ViewModel中的方法,但是回来后,在自己的机器上写了一个类似的测试程序时,却能够调用ViewModel中的方法

测试程序DataGrid

 1 <DataGrid CanUserAddRows="False" AutoGenerateColumns="True" ItemsSource="{Binding Collection, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
 2                 >
 3                 <DataGrid.ContextMenu>
 4                     <ContextMenu Name="menuList" >                        
 5                         <MenuItem Header="查看" cal:Message.Attach="[Event Click]=[Action Show()];">
 6                         </MenuItem>
 7                         <MenuItem Header="修改一下">
 8                             <MenuItem Header="修改" cal:Message.Attach="[Event Click]=[Action Modify()];"></MenuItem>
 9                             <MenuItem Header="删除" cal:Message.Attach="[Event Click]=[Action Delete()]"></MenuItem>
10                         </MenuItem>
11                     </ContextMenu>
12                 </DataGrid.ContextMenu>
13 
14                 <DataGrid.Columns>
15                     <DataGridTemplateColumn Header="姓名" Width="100">
16                         <DataGridTemplateColumn.CellTemplate>
17                             <DataTemplate>
18 
19                                 <TextBlock Text="{Binding Path=Name, Mode=TwoWay}"/>
20                             </DataTemplate>
21                         </DataGridTemplateColumn.CellTemplate>
22                     </DataGridTemplateColumn>
23 
24                     <DataGridTemplateColumn Header="性别" Width="100">
25                         <DataGridTemplateColumn.CellTemplate>
26                             <DataTemplate>
27 
28                                 <TextBlock Text="{Binding Path=Sex, Mode=TwoWay}" />
29                             </DataTemplate>
30                         </DataGridTemplateColumn.CellTemplate>
31                     </DataGridTemplateColumn>
32                     <DataGridTemplateColumn Header="年龄" Width="100">
33                         <DataGridTemplateColumn.CellTemplate>
34                             <DataTemplate>
35 
36                                 <TextBlock Text="{Binding Path=Age, Mode=TwoWay}"/>
37                             </DataTemplate>
38                         </DataGridTemplateColumn.CellTemplate>
39                     </DataGridTemplateColumn>
40                 </DataGrid.Columns>
41             </DataGrid>

ViewModel中对应的方法

 1 public void Show()
 2         {
 3             MessageBox.Show("查看成功");
 4         }
 5 
 6         public void Modify()
 7         {
 8             MessageBox.Show("修改成功");
 9         }
10 
11         public  void Delete()
12         {
13             MessageBox.Show("删除成功");
14         }

在公司时,一级MenuItem中也无法调用ViewModel中的方法,原因应该是MenuItem与DataGrid不在一个视觉树中。由于无法复现问题,只能修改测试程序将我找到的解决方法贴出来。

 1 <DataGrid CanUserAddRows="False" AutoGenerateColumns="True" ItemsSource="{Binding Collection, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
 2                 >
 3                 <DataGrid.ContextMenu>
 4                     <ContextMenu Name="menuList" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">                        
 5                         <MenuItem Header="查看" cal:Message.Attach="[Event Click]=[Action Show()];">
 6                         </MenuItem>
 7                         <MenuItem Header="修改一下">
 8                             <MenuItem Header="修改" 
 9 cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" 
10 cal:Message.Attach="[Event Click]=[Action Modify()];">
11 </MenuItem>
12                             <MenuItem Header="删除" 
13 cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" 
14 cal:Message.Attach="[Event Click]=[Action Delete()]">
15 </MenuItem>
16                         </MenuItem>
17                     </ContextMenu>
18                 </DataGrid.ContextMenu>
19 
20                 <DataGrid.Columns>
21                     <DataGridTemplateColumn Header="姓名" Width="100">
22                         <DataGridTemplateColumn.CellTemplate>
23                             <DataTemplate>
24 
25                                 <TextBlock Text="{Binding Path=Name, Mode=TwoWay}"/>
26                             </DataTemplate>
27                         </DataGridTemplateColumn.CellTemplate>
28                     </DataGridTemplateColumn>
29 
30                     <DataGridTemplateColumn Header="性别" Width="100">
31                         <DataGridTemplateColumn.CellTemplate>
32                             <DataTemplate>
33 
34                                 <TextBlock Text="{Binding Path=Sex, Mode=TwoWay}" />
35                             </DataTemplate>
36                         </DataGridTemplateColumn.CellTemplate>
37                     </DataGridTemplateColumn>
38                     <DataGridTemplateColumn Header="年龄" Width="100">
39                         <DataGridTemplateColumn.CellTemplate>
40                             <DataTemplate>
41 
42                                 <TextBlock Text="{Binding Path=Age, Mode=TwoWay}"/>
43                             </DataTemplate>
44                         </DataGridTemplateColumn.CellTemplate>
45                     </DataGridTemplateColumn>
46                 </DataGrid.Columns>
47             </DataGrid>

参考自:http://stackoverflow.com/questions/13587368/no-target-found-for-method-thrown-by-caliburn-message-attach

原文地址:https://www.cnblogs.com/shuqiangji/p/3916880.html