In Caliburn.Micro how to bind action to nested ViewModel method?

北城余情 提交于 2019-12-05 12:19:43

Here is my workaround:

private static void EnableNestedViewModelActionBinding()
{
    var baseGetTargetMethod = ActionMessage.GetTargetMethod;
    ActionMessage.GetTargetMethod = (message, target) =>
    {
        var methodName = GetRealMethodName(message.MethodName, ref target);
        if (methodName == null)
            return null;

        var fakeMessage = new ActionMessage { MethodName = methodName };
        foreach (var p in message.Parameters)
            fakeMessage.Parameters.Add(p);
        return baseGetTargetMethod(fakeMessage, target);
    };

    var baseSetMethodBinding = ActionMessage.SetMethodBinding;
    ActionMessage.SetMethodBinding = context =>
    {
        baseSetMethodBinding(context);
        var target = context.Target;
        if (target != null)
        {
            GetRealMethodName(context.Message.MethodName, ref target);
            context.Target = target;
        }
    };
}

private static string GetRealMethodName(string methodName, ref object target)
{
    var parts = methodName.Split('.');
    var model = target;
    foreach (var propName in parts.Take(parts.Length - 1))
    {
        if (model == null)
            return null;

        var prop = model.GetType().GetPropertyCaseInsensitive(propName);
        if (prop == null || !prop.CanRead)
            return null;

        model = prop.GetValue(model);
    }
    target = model;
    return parts.Last();
}

Call EnableNestedViewModelActionBinding() once from your bootstrapper and it will allow you to bind actions to nested model's methods using the usual dotted notation. E.g.

cal:Message.Attach="[Event Click] = [Action UserNotFoundWarning.ShowWarning]"

Edit: please note, that this wouldn't work if you change the nested ViewModel instance at runtime. E.g. if you assign your UserNotFoundWarning to something new after the binding happened - Caliburn would still call actions on previous instance.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!