今天一个朋友,在用CM框架中,在一个ListView的DataTemplate,中用了个Popup,发现绑定不到VM(集合外的VM,即ListView的DataContext)中的方法了。我查了一下CM的源码,固留档在此。
在CM框架中,绑定方法,如果当前的DataContext没有找到对应的方法,会去遍历VisualTree,上的对象的 DataContext , 至到找到对应的方法或 遍历完成。
但是 Popup 他的本质就是一个窗口,他等于是自有VisualTree,他的根是PopupRoot, 在对PopupRoot再掉用 VisualTreeHelper.GetParent时,返回值为null。
其实我们要做的就是,在发现是 PopupRoot的时候,处理一下。
代码:
ActionMessage.SetMethodBinding = context => { var source = context.Source; DependencyObject currentElement = source; while (currentElement != null) { if (Action.HasTargetSet(currentElement)) { var target = Message.GetHandler(currentElement); if (target != null) { var method = ActionMessage.GetTargetMethod(context.Message, target); if (method != null) { context.Method = method; context.Target = target; context.View = currentElement; return; } } else { context.View = currentElement; return; } } //修改部分 Begin var pElement = VisualTreeHelper.GetParent(currentElement); if (pElement == null && currentElement.GetType().Name.Equals("PopupRoot", StringComparison.OrdinalIgnoreCase)) { var ef = currentElement as FrameworkElement; if (ef != null) { pElement = ef.Parent; } } currentElement = pElement; //End } if (source != null && source.DataContext != null) { var target = source.DataContext; var method = ActionMessage.GetTargetMethod(context.Message, target); if (method != null) { context.Target = target; context.Method = method; context.View = source; } } };
只有红的部分是我修改了的,别的地方都为源码中的。
PS:
因为CM只能算是一个小众的框架,稍稍的扫下盲,指对这一块,对此有了解的可以略过。
CM中好多的方法是用静态委托方式实现的,而且还是公有的,我们很容易的在外面对其进行重写,而不用去重新编辑源码。So Cool!
本文原创
转载请注明出处:http://www.cnblogs.com/gaoshang212/p/4203929.html
本文原创手打,转载请注明出处。 Electron 交流 QQ:160162552