Caliburn.Micro(CM) 穿过 Popup 绑定方法

今天一个朋友,在用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!

本文原创

做事的能力往往只能给你一种机会,

Caliburn.Micro(CM) 穿过 Popup 绑定方法

相关文章:

你感兴趣的文章:

标签云: