WPF:在运行时替换页面或用户控件的 XAML(两者都可以)?

发布于 2024-09-06 19:18:09 字数 211 浏览 3 评论 0原文

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

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

推理:

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

I know that it is possible to parse an XAML - file at runtime and create an UIElement which I can insert into my pages grid, no problem there.

But what I really want is to replace the whole XAML of my page or usercontrol, is that possible, too?

Reasoning:

I want to give the users of my application the opportunity to have the application run (startup takes ages - and that can't be shortened because of some legacy issues) and simply update the view by "ctrl + s" in Blend.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

街道布景 2024-09-13 19:18:09

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

优秀的纯 MVVM 应用程序

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

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

 Application.LoadComponent(this, uriToTemporaryCopy);

丑陋的不纯非 MVVM 应用程序

现在,我们假设您使用了一个名为的元素x: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。如果直接调用标记编译器任务,您可以决定输出位置。

什么是 BAML 文件?

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

It depends on whether you attach event handlers or use the "Name" or "x:Name" attribute to access UI elements from code.

Nice pure MVVM application

First let's assume you have a nice pure MVVM application that uses binding and commands exclusively, so you aren't using named UI elements or code-behind event handlers. Good for you: You have a nice clean application architecture and I like you.

In that case all you need to do is create a temporary copy of your XAML file with the x:Class attribute removed, and call:

 Application.LoadComponent(this, uriToTemporaryCopy);

Ugly impure non-MVVM application

Now let's assume you used an element named with x:Name or Name from your code-behind (naughty, naughty, naughty!), or you attached an event handler using XAML (less naughty but not pure either). You don't have a nice clean architecture, but I still like you anyway.

In this case, Application.LoadComponent won't do the trick by itself because these settings require integration with the code-behind. You also need to find a way to invoke the BAML compiler.

Since the code-behind integration is already compiled into your Page or UserControl subclass, there are some restrictions:

  1. You cannot add, remove, or change the sequence of event handler assignments
  2. You cannot change the names or sequences of named elements or add more named elements

If you abide by these rules, in general the generated code that is incorporated into your class will not change, therefore you can load the new XAML file into a running application without breaking anything.

The procedure is:

  1. Compile the XAML file to BAML either by A) building the containing project, B) creating a temporary project and compiling that, or C) directly calling the markup compiler tasks in PresentationBuildTasks.
  2. Use Application.LoadComponent to load the BAML file just as you did for the edited XAML file in the pure solution.

In a compiled .csproj project, any compiled BAML files will be found under the obj/debug or obj/release directory with an extension of .baml. If you call the markup compiler task directly you can decide on the output location.

What is a BAML file?

For those who don't know, BAML is basically a compressed and optimized binary form of XAML, and is the way your XAML is stored inside your .exe or .dll. It also has capabilities for linking directly to generated code, which XAML does not have.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文