XamlWriter.Save 的序列化限制

API Save 可用于将 Windows Presentation Foundation (WPF) 应用程序的内容序列化为可扩展应用程序标记语言(XAML)文件。 但是,对于所序列化的内容有一些显著限制。 本主题介绍了这些限制和一些常规注意事项。

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

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

序列化是自包含的

Save 的序列化输出是自包含的;序列化的所有内容都包含在 XAML 单页中,其中包含单个根元素,并且没有 URI 以外的外部引用。 例如,如果页面引用了应用程序资源中的资源,这些资源将显示为正在序列化的页面的组件。

取消引用扩展引用

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

不保留事件处理

通过 XAML 添加的事件处理程序在序列化时不会被保留。 没有代码隐藏的 XAML(以及没有相关的 x:Code 机制)无法序列化运行时过程逻辑。 由于序列化是自包含的,并且仅限于逻辑树,因此没有用于存储事件处理程序的设施。 因此,事件处理程序属性(属性本身和命名处理程序的字符串值)将从输出 XAML 中删除。

XAMLWriter.Save 的实际使用情景

虽然此处列出的限制相当大,但仍有几个适当的方案可用于使用 Save 进行序列化。

  • 矢量或图形输出:在重新加载时,可以使用呈现区域的输出来重现相同的向量或图形。

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

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