1

我知道可以在运行时解析一个 XAML - 文件并创建一个 UIElement,我可以将其插入到我的页面网格中,没有问题。

但我真正想要的是替换我的页面或用户控件的整个 XAML,这也可能吗?

推理:

我想让我的应用程序的用户有机会运行应用程序(启动需要很长时间 - 由于一些遗留问题而无法缩短),并且只需在 Blend 中通过“ctrl + s”更新视图。

4

1 回答 1

3

这取决于您是附加事件处理程序还是使用“Name”或“x:Name”属性从代码访问 UI 元素。

不错的纯 MVVM 应用程序

首先让我们假设您有一个很好的纯 MVVM 应用程序,它专门使用绑定和命令,因此您没有使用命名的 UI 元素或代码隐藏事件处理程序。对你有好处:你有一个干净整洁的应用程序架构,我喜欢你。

在这种情况下,您需要做的就是创建 XAML 文件的临时副本,并删除 x:Class 属性,然后调用:

 Application.LoadComponent(this, uriToTemporaryCopy);

丑陋的非 MVVM 应用程序

现在让我们假设您在代码隐藏中使用了一个以 x:Name 或 Name 命名的元素(顽皮、顽皮、顽皮!),或者您使用 XAML 附加了一个事件处理程序(不那么顽皮,但也不纯粹)。你没有漂亮干净的架构,但我还是喜欢你。

在这种情况下,Application.LoadComponent 本身并不能解决问题,因为这些设置需要与代码隐藏集成。您还需要找到一种方法来调用 BAML 编译器。

由于代码隐藏集成已经编译到您的 Page 或 UserControl 子类中,因此存在一些限制:

  1. 您不能添加、删除或更改事件处理程序分配的顺序
  2. 您不能更改命名元素的名称或序列或添加更多命名元素

如果您遵守这些规则,通常合并到您的类中的生成代码不会更改,因此您可以将新的 XAML 文件加载到正在运行的应用程序中而不会破坏任何内容。

程序是:

  1. 将 XAML 文件编译为 BAML,方法是 A) 构建包含项目,B) 创建一个临时项目并编译它,或者 C) 直接调用 PresentationBuildTasks 中的标记编译器任务。
  2. 使用 Application.LoadComponent 加载 BAML 文件,就像在纯解决方案中对已编辑的 XAML 文件所做的那样。

在已编译的 .csproj 项目中,任何已编译的 BAML 文件都将位于 obj/debug 或 obj/release 目录下,扩展名为 .baml。如果您直接调用标记编译器任务,您可以决定输出位置。

什么是一 .bml 文件?

对于那些不知道的人,BAML 基本上是一种压缩和优化的 XAML 二进制形式,并且是 XAML 存储在 .exe 或 .dll 中的方式。它还具有直接链接到生成的代码的功能,而 XAML 没有这些功能。

于 2010-06-24T07:03:33.757 回答