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, 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, 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

Caliburn框架中二级Menu无法调用ViewModel方法,布布扣,bubuko.com

时间: 2024-12-19 11:19:54

Caliburn框架中二级Menu无法调用ViewModel方法的相关文章

YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法

上一篇介绍了 MVC中实现动态自定义路由 的实现,本篇将介绍Razor视图中以全局方式调用后台方法输出页面代码的三种方法. 框架最新的升级实现了一个页面部件功能,其实就是通过后台方法查询数据库内容,把查询结果的 HTML 代码呈现到 Razor 视图中,考虑到灵活性,需要能在任意 Razor 视图中调用该方法,这样任意 Razor 页面都能以统一的方式方便地共享该页面部件的 HTML 内容,这对于代码的重用性和可维护性都是非常有必要的. 为实现上述要求,本文介绍如下可供选择的三种方式.   1.

knockout.js(js)代码在IE中出现“意外地调用了方法或属性”的错误

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 var CartListViewModel = function () {     var self = this;     self.payment = [                 { name: "", value: 1

cocos2d 中使用jni C++ 调用 Java 方法

1.简单数据类型例子 假设我们Java中有这么一个open的静态方法,它没有参数,有一个int的返回值.怎么在C++中调用它呢? package cb.CbCCBLE; public class CbCCBLECentralManager { public static final String TAG = "CbCCBLECentralManager Android"; public static int open() { Log.d(TAG,"open"); r

cocos2d 中使用jni Java 调用 C++ 方法

1.首先是LoadLibrary cocos2d中的C++代码会编译成一个.so文件,放在安卓目录下的libs/armeabi 下,然后java会load进来,这步我们不用做了,因为cocos2d已经帮我们做好了. package cb.CbCCBLE; public class CbCCBLECentralManager { public static final String TAG = "CbCCBLECentralManager Android"; public native

C#中事件的动态调用实现方法

本文实例讲述了C#动态调用事件的方法.一般来说,传统的思路是,通过Reflection.EventInfo获得事件的信息,然后使用GetRaiseMethod方法获得事件被触发后调用的方法,再使用MethodInfo.Invoke来调用以实现事件的动态调用. 但是很不幸的,Reflection.EventInfo.GetRaiseMethod方法始终返回null.这是因为,C#编译器在编译并处理由event关键字定义的事件时,根本不会去产生有关RaiseMethod的元数据信息,因此GetRai

详述 Spring MVC 框架中拦截器 Interceptor 的使用方法

1 前言 昨天新接了一个需要,"拦截 XXX,然后 OOO",好吧,说白了就是要用拦截器干点事(实现一个具体的功能).之前,也在网络上搜了很多关于Interceptor的文章,但感觉内容都大同小异,而且知识点零零散散,不太方便阅读.因此,正好借此机会,整理一篇关于拦截器的文章,在此分享给大家,以供大家参考阅读. 2 拦截器 2.1 概念 Java 里的拦截器是动态拦截 action 调用的对象.它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个

让NSArray数组中每个对象都调用的方法

1. [array valueForKey:@"title"]; //Returns an array containing the results of invoking valueForKey: using key on each of the array's objects. 使数组中的每个对象都调用valueForKey:方法,并且将每个对象调用方法的结果依次存入一个新的数组中,然后返回 2. [self  setValuesForKeysWithDictionary:dict

cocos2d-x中使用JNI的调用JAVA方法

用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化语言(如C\C++)与JAVA语言进行交互.在交互过程成中,JAVA调用的是已编译好的本地化语言的二进制代码(如Windows下的dll.Linux下的so文件).所以在交叉编译时看到Eclipse的控制台输出 [armeabi] SharedLibrary  : libcocos2dcpp.so

ongl表达式中得到对象,调用对象方法(OA项目权限显示模块)

在用户是否拥有某项权限的问题  是这样解决的: 用户登录之后  登录信息是保存在session域中的  通过el表达式可得到登录的对象信息  那么怎样判断用户是否拥有某项权限呢 ?如果没有上图中的判断 那么登录或者不登录  访问首页的时候 就会显示所有的权限列表(即操作菜单) 这些权限信息是在服务器启动的时候  检索并且保存在了application中的(可以看上一篇博客总结)  所以在遍历的时候 如果不加判断  默认显示的是所有的权限信息  即操作菜单 首先理清思路  user用户 中存在ro