XamlWriter.Save 的序列化限制

API Save 可用于将 Windows Presentation Foundation (WPF) 应用程序的内容序列化为 Extensible Application Markup Language (XAML) 文件。 但是,对于所序列化的内容有一些显著限制。 本主题对这些限制和某些一般注意事项进行了介绍。

运行时、非设计时表示形式

对于通过调用 Save 进行序列化的内容,基本原则是:其结果为在运行时生成序列化对象的表示形式。 在将 XAML 加载为内存中对象时,原始 XAML 文件的许多设计时属性可能已经优化或丢失,而且在调用 Save 进行序列化时未保留这些属性。 序列化的结果是应用程序的结构化逻辑树的有效表示形式,但并不一定是生成该树的原始 XAML 的有效表示形式。 这些问题导致将 Save 序列化用作大型 XAML 设计图面的一部分变得极为困难。

序列化是自包含的

Save 的序列化输出是自包含的;序列化的所有内容都包含在单个 XAML 页面中,具有单个根元素,而且不存在 URI 以外的外部引用。 例如,如果页面从应用程序资源引用了资源,则这些资源看上去如同正在进行序列化的页面的一个组件。

取消引用扩展引用

由各种标记扩展格式(如 StaticResourceBinding)对对象进行的公共引用将会由序列化进程取消引用。 当应用程序运行时创建内存中对象时,已对这些公共引用取消引用,且 Save 逻辑不会重新访问原始的 XAML 来将这些引用还原到序列化的输出。 这样可能会将任何数据绑定的或资源获得的值冻结为运行时表示形式最后使用的值,并且只能有限地或间接地区别这样的值与任何其他在本地设置的值。 由于图像存在于项目中,因此图像也会序列化为图像的对象引用(而不是原始的源引用),从而会丢失最初引用的文件名或 URI。 即使是在同一页面内声明的资源,也会序列化到引用点内,而不是保留为资源集合的键。

不保留事件处理

当对通过 XAML 添加的事件处理程序进行序列化后,不会保留这些事件处理程序。 不具有代码隐藏功能(并且也不具有相关的 x:Code 机制)的 XAML 无法对运行时过程逻辑进行序列化。 因为序列化是自包含的且限于逻辑树,所以不存在用于存储事件处理程序的设施。 因此,会从输出 XAML 中删除事件处理程序特性(特性本身和用于命名处理程序的字符串值)。

XAMLWriter.Save 实用方案

虽然此处列出了较多限制,但仍然存在几个适合使用 Save 进行序列化的方案。

  • 向量或图形输出:所呈现的区域的输出可用于在重新加载时重新生成相同的向量或图形。

  • 格式文本和流文档:输出中会保留文本以及文本内的所有元素格式和元素所含内容。 这对类似于剪贴板功能的机制可能非常有用。

  • 保留业务对象数据:如果已在自定义元素中存储数据(如 XML 数据),只要业务对象遵循基本 XAML 规则(如为按引用属性值提供自定义构造函数和转换),这些业务对象就可以通过序列化永久保留。