WPF:在运行时替换页面或usercontrol的XAML(都可以)?
-
29-09-2019 - |
题
我知道可以在运行时解析XAML - 文件,并创建一个可以插入我的页面网格中的UIELEMENT,那里没问题。
但是,我真正想要的是替换我的页面或UserControl的整个XAML,这也可能吗?
推理:
我想为我的应用程序用户提供机会进行应用程序运行(启动需要年龄 - 并且由于某些遗产问题而不能缩短),然后简单地通过“ CTRL + S”更新视图。
解决方案
这取决于您是附上事件处理程序还是使用“名称”或“ x:name”属性从代码访问UI元素。
不错的纯MVVM应用程序
首先,让我们假设您有一个不错的纯MVVM应用程序,该应用程序专门使用绑定和命令,因此您不使用名为UI元素或代码范围事件处理程序。对您有好处:您有一个不错的干净应用程序体系结构,我喜欢您。
在这种情况下,您需要做的就是使用X:class属性删除XAML文件的临时副本,并致电:
Application.LoadComponent(this, uriToTemporaryCopy);
丑陋的非MVVM应用程序
现在,假设您使用了一个名为x:name-behind(顽皮,顽皮,顽皮!)的元素,或者使用XAML(不太顽皮但也不纯)附加了事件处理程序。您没有很好的干净建筑,但无论如何我仍然喜欢您。
在这种情况下,application.loadcomponent不会单独执行问题,因为这些设置需要与代码范围集成。您还需要找到一种调用BAML编译器的方法。
由于代码积分已被编译到您的页面或USERCORTROL子类中,因此有一些限制:
- 您无法添加,删除或更改事件处理程序分配的顺序
- 您不能更改命名元素的名称或序列或添加更多命名元素
如果您遵守这些规则,则通常将合并到类的生成的代码不会更改,因此您可以将新的XAML文件加载到正在运行的应用程序中而无需破坏任何内容。
该过程是:
- 通过a)构建包含项目,b)创建一个临时项目并编译该XAML文件,或者c)直接调用Markup编译器任务。
- 使用application.loadcomponent,就像您对纯解决方案中编辑的XAML文件一样加载BAML文件。
在一个编译的.CSPROJ项目中,将在OBJ/调试或OBJ/Release目录下找到任何编译的BAML文件,并扩展为.baml。如果您直接调用标记编译器任务,则可以决定输出位置。
什么是BAML文件?
对于那些不知道的人,BAML基本上是XAML的压缩和优化的二进制形式,并且是XAML存储在.exe或.dll中的方式。它还具有直接链接到生成代码的功能,XAML没有。