XamlWriter.Save 的序列化限制

更新:2007 年 11 月

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

本主题包括下列各节。

  • 运行时表示形式而非设计时表示形式
  • 序列化是独立的
  • 取消引用扩展引用
  • 不保留事件处理
  • 使用 XAMLWriter.Save 的真实方案

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

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

序列化是独立的

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

取消引用扩展引用

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

不保留事件处理

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

使用 XAMLWriter.Save 的真实方案

虽然这里列出的限制相当多,但仍然有几种适当的方案适合使用 Save 进行序列化。

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

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

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