在 Caliburn.Micro 中如何将操作绑定到嵌套的 ViewModel 方法?

2024-02-20

我有一个 WPF 应用程序,由 Caliburn.Micro 提供支持,视图模型优先方法。有一种命令栏类型的控件,其CommandBarView.xaml并绑定命令栏视图模型。命令栏虚拟机包含许多嵌套虚拟机,每个虚拟机对应一个按钮控件,所有虚拟机都显示通用界面并具有通用行为。命令栏虚拟机公开它们,以便可以从视图中绑定它们:

public interface IWarningButtonViewModel
{
    bool IsVisible { get; }
    bool CanShowWarning { get; }
    void ShowWarning();
}

public class CommandBarViewModel : PropertyChangedBase
{
    public IWarningButtonViewModel UserNotFoundWarning { get; private set; }
    public IWarningButtonViewModel NetworkProblemWarning { get; private set; }
    // ... initialization omitted for simplicity
}

这是 CommandBarView 的暂定 XAML:

<Button x:Name="UserNotFoundWarning_ShowWarning"
        IsEnabled="{Binding UserNotFoundWarning.CanShowWarning}">
  ... 
  <DataTrigger Binding="{Binding UserNotFoundWarning.IsVisible}" Value="True">
  ...
</Button>

通过这种方式,我能够成功绑定两个属性(可以显示警告, 可见)但我无法将按钮命令/操作绑定到显示警告 method.

我尝试过深度属性绑定 https://joshearl.wordpress.com/2011/03/24/deep-property-databinding-with-caliburn-micro/这同样适用于属性,但不适用于行动。
我也尝试过混合使用cal:Model.Bind and cal:Message.Attach:

<Button cal:Model.Bind="{Binding UserNotFoundWarning}" 
        cal:Message.Attach="[Event Click] = [Action ShowWarning]"
        IsEnabled="{Binding CanShowWarning}">
  ... 
  <DataTrigger Binding="{Binding IsVisible}" Value="True">
  ...
</Button>

这似乎在运行时有效,但是cal:模型.绑定使 VS 设计器完全无法使用,UI 控件不显示。

我已经搜索了很多,但我找不到一个实际的解决方案,让我也可以与设计师合作。对我来说,我只能找到属性深度绑定的示例,而不能找到操作的示例,这似乎很奇怪。

知道如何解决这个问题吗?


这是我的解决方法:

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()一旦来自引导程序,它将允许您使用通常的点符号将操作绑定到嵌套模型的方法。例如。

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

Edit:请注意,如果您在运行时更改嵌套的 ViewModel 实例,这将不起作用。例如。如果你分配你的UserNotFoundWarning绑定发生后发生新的事情 - Caliburn 仍会调用前一个实例的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Caliburn.Micro 中如何将操作绑定到嵌套的 ViewModel 方法? 的相关文章

  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 唯一索引不适用于 Mongoose / MongoDB

    我在使用 Mongoose MongoDb 创建唯一索引时遇到问题 无法让它工作 当我设置唯一索引时 我可以添加两个具有相同属性值的文档 我已经尝试了我能想到的一切 重新启动 一切 更改语法等 Code Addtion gt gt 这是我用
  • MongoDB 如何评估多个 $or 语句?

    MongoDB 将如何评估此查询 db testCol find or a 1 b 12 b 9 c 15 c 10 d foo 当扫描文档中的值时 如果第一个 OR 语句为 TRUE 其他语句也会被评估吗 从逻辑上讲 如果 MongoDB
  • 如何防止 UIButton 在按下时突出显示?

    When an UIButton按下后 正常情况是它会突出显示 即阴影层会覆盖图像 有没有办法防止这种情况发生 有没有一个属性可以处理这个问题 通常 您不会使用 Xcode 按按钮 而是使用手指 或鼠标 但撇开挑剔不谈 adjustsIma
  • 使用 JQuery Mobile 向上或向下移动控制组中的多个链接

    这是我上一个问题的后续问题 控制组 JQuery Mobile 上有 3 个水平按钮 多行 https stackoverflow com questions 26088729 controlgroup 3 buttons horizont
  • 使用 JS 在 Google Apps 脚本文档中查找未知字符串并将其更改为大写

    我写在Fountain markdown http fountain io http fountain io 在谷歌文档中 喷泉是用来写剧本的 我想通过自动大写某些元素 打开或使用按钮等 使喷泉中的书写更加友好 这是一个格式正确的剧本 在喷
  • 哪个 django OpenID 库可与新的 Google OpenID 配合使用

    由于 Google 弃用了 OpenID 2 0https developers google com accounts docs OpenID2 https developers google com accounts docs Open
  • 如何使符号计算中的所有低值都变为零?

    如何将 SymPy 表达式中的所有低值设为零 例如我的结果是 1 0 a1 cos q1 6 12e 17 a2 sin q2 a3 sin q2 q3 a4 sin q2 q3 q4 sin q1 1 0 a2 cos q2 a3 cos
  • Python中计算二叉树的深度

    我是编程新手 正在尝试计算 Python 中二叉树的深度 我相信我的错误是因为深度是 Node 类的方法而不是常规函数 我正在尝试学习OOP并希望使用一种方法 这可能是一个新手错误 这是我的代码 class Node def init se
  • OpenCL 在线编译:从 cl::program 或 cl::kernel 获取程序集

    我正在使用 OpenCL 运行内核基准测试 我知道我可以使用 OpenCL 供应商提供的各种工具离线编译内核 即ioc64 or poclcc 问题是我得到的性能结果无法用这些工具的汇编 OpenCL 运行时开销或类似的来解释 我想看到由我
  • 我无法删除 Azure AD 门户中的本机应用程序注册

    我只想删除出于测试目的而创建的 AD 应用程序注册 我无法删除它 因为删除按钮呈灰色 在我删除另一个未使用的应用程序之前没有任何问题 有什么建议么 游戏有点晚了 但是当尝试上述步骤时 它们对我不起作用 总是被禁用 并且由于某种原因 我无法将
  • 整个计算机处于 Git 状态未跟踪文件

    我是 git 新手 我想我不小心克隆到了根目录中 当我提交一个文件 index html 时 我注意到我的整个计算机 我的桌面 我的文档等 都在未跟踪的文件中 我删除了存储库 并且想删除所有未跟踪的文件 显然不想删除计 算机中的所有内容 我
  • 在 Safari 中打开 WebView 链接

    我正在 Cocoa 中开发一个应用程序 我想知道是否有一种方法 如何使我的 webview 中单击的任何链接在 Safari 或默认浏览器 中启动 提前致谢 我自己刚刚遇到了这个问题 并通过以下方式解决了它 我的主控制器对象被设置为 Web
  • 捕获 C++ 库崩溃的一致方法

    我浏览了不同的网站 除了那些似乎不起作用的网站之外 找不到这个问题的任何答案 正如标题所示 我正在尝试找到一种方法来捕获我正在处理的库是否崩溃 我有一个 Root 类 它保存我的库中的许多管理器样式类的实例 并在其析构函数中释放这些实例 当
  • 在reactjs中悬停时显示组件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我创建了几个带有特定内容标题的部分 我想在悬停在不同部分上方时显示一个简短的预览 有谁知道如何创建一个具有条件渲染反应组件的hover
  • 冒泡排序双向链表

    我的双向链表冒泡排序功能有问题 当我以单链接方式对节点进行排序时 仅使用 gt next 它可以工作 但我无法使其与 gt prev 指针一起使用 这是我正在使用的代码 void sort int count struct data tmp
  • 无法更新 Dynamodb 表,出现 ValidationException

    我需要仅使用分区键来更新我的 dynamodb 表 但我得到了验证异常 我创建了一个包含 3 个字段的表 id 分区键 名称 排序键 age 然后我尝试仅使用 id 更新年龄字段 尝试将年龄 30 修改为 40 这是我的代码 var AWS
  • 如何调试 gulp-sourcemaps 不执行任何操作?

    我有一个相当标准的用例gulp sourcemaps https github com floridoo gulp sourcemaps https github com floridoo gulp sourcemaps gulp src
  • SQLAlchemy 获取匹配查询的每一行并循环遍历它们

    我是 Python 和 SQLAlchemy 的新手 我一直在尝试从数据库中检索内容 并且每次都有效 但我有点不确定当 select 语句将返回多行时该怎么做 我尝试使用一些在开始 SQLAlchemy 之前有效的旧代码 但是db是一个 S
  • Google PHP API 客户端:CA 证书错误

    我正在尝试与 Google PHP API 客户端交互 但 Google 提供的证书存在问题 谷歌错误 SSL certificate problem verify that the CA cert is OK Retrying with
  • 在 Caliburn.Micro 中如何将操作绑定到嵌套的 ViewModel 方法?

    我有一个 WPF 应用程序 由 Caliburn Micro 提供支持 视图模型优先方法 有一种命令栏类型的控件 其CommandBarView xaml并绑定命令栏视图模型 命令栏虚拟机包含许多嵌套虚拟机 每个虚拟机对应一个按钮控件 所有