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

时间:2010-06-24 04:21:52

标签: .net wpf xaml xamlreader

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

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

推理:

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

1 个答案:

答案 0 :(得分: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. 您无法更改命名元素的名称或序列,也无法添加更多命名元素
  3. 如果您遵守这些规则,通常生成的代码将不会更改,因此您可以将新的XAML文件加载到正在运行的应用程序中而不会破坏任何内容。

    程序是:

    1. 通过A)构建包含项目,B)创建临时项目并编译它,或者C)直接调用PresentationBuildTasks中的标记编译器任务,将XAML文件编译为BAML。
    2. 使用Application.LoadComponent加载BAML文件,就像在纯解决方案中对已编辑的XAML文件所做的那样。
    3. 在已编译的.csproj项目中,任何已编译的BAML文件都将在obj / debug或obj / release目录下找到,扩展名为.baml。如果直接调用标记编译器任务,则可以决定输出位置。

      什么是BAML文件?

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