我知道可以在运行时解析一个 XAML - 文件并创建一个 UIElement,我可以将其插入到我的页面网格中,没有问题。
但我真正想要的是替换我的页面或用户控件的整个 XAML,这也可能吗?
推理:
我想让我的应用程序的用户有机会运行应用程序(启动需要很长时间 - 由于一些遗留问题而无法缩短),并且只需在 Blend 中通过“ctrl + s”更新视图。
我知道可以在运行时解析一个 XAML - 文件并创建一个 UIElement,我可以将其插入到我的页面网格中,没有问题。
但我真正想要的是替换我的页面或用户控件的整个 XAML,这也可能吗?
推理:
我想让我的应用程序的用户有机会运行应用程序(启动需要很长时间 - 由于一些遗留问题而无法缩短),并且只需在 Blend 中通过“ctrl + s”更新视图。
这取决于您是附加事件处理程序还是使用“Name”或“x:Name”属性从代码访问 UI 元素。
不错的纯 MVVM 应用程序
首先让我们假设您有一个很好的纯 MVVM 应用程序,它专门使用绑定和命令,因此您没有使用命名的 UI 元素或代码隐藏事件处理程序。对你有好处:你有一个干净整洁的应用程序架构,我喜欢你。
在这种情况下,您需要做的就是创建 XAML 文件的临时副本,并删除 x:Class 属性,然后调用:
Application.LoadComponent(this, uriToTemporaryCopy);
丑陋的非 MVVM 应用程序
现在让我们假设您在代码隐藏中使用了一个以 x:Name 或 Name 命名的元素(顽皮、顽皮、顽皮!),或者您使用 XAML 附加了一个事件处理程序(不那么顽皮,但也不纯粹)。你没有漂亮干净的架构,但我还是喜欢你。
在这种情况下,Application.LoadComponent 本身并不能解决问题,因为这些设置需要与代码隐藏集成。您还需要找到一种方法来调用 BAML 编译器。
由于代码隐藏集成已经编译到您的 Page 或 UserControl 子类中,因此存在一些限制:
如果您遵守这些规则,通常合并到您的类中的生成代码不会更改,因此您可以将新的 XAML 文件加载到正在运行的应用程序中而不会破坏任何内容。
程序是:
在已编译的 .csproj 项目中,任何已编译的 BAML 文件都将位于 obj/debug 或 obj/release 目录下,扩展名为 .baml。如果您直接调用标记编译器任务,您可以决定输出位置。
什么是一 .bml 文件?
对于那些不知道的人,BAML 基本上是一种压缩和优化的 XAML 二进制形式,并且是 XAML 存储在 .exe 或 .dll 中的方式。它还具有直接链接到生成的代码的功能,而 XAML 没有这些功能。