移除设计器添加到 XAML 文件的视图状态

ViewStateCleaningWriter示例演示如何创建派生自 XamlWriter 的类以及如何从 XAML 文件中移除视图状态。 Windows 工作流设计器会将信息写入称作视图状态的 XAML 文档中。 视图状态是指设计时所需的信息(如布局定位),运行时不需要此信息。 工作流设计器将此信息插入正在编辑的 XAML 文档中。 工作流设计器使用 mc:Ignorable 特性将视图状态写入 XAML 文件中,因此在运行时加载 XAML 文件时不会加载此信息。 此示例演示如何创建一个类,此类将在处理 XAML 节点时移除视图状态信息。

讨论 (Discussion)

此示例演示如何创建自定义编写器。

若要生成自定义 XAML 编写器,请创建一个从 XamlWriter 继承的类。 由于 XAML 编写器经常是嵌套的,因此通常将跟踪“内部”XAML 编写器。 可将这些“内部”编写器视为对 XAML 编写器的剩余堆栈的引用,这使您能够通过多个入口点执行工作,然后将处理委托给堆栈的其余部分。

在此示例中,有几个需要注意的地方。 其中一个需要注意的是,检查要编写的项是否来自某个设计器命名空间。 请注意,此操作还将消除工作流中对该设计器命名空间的其他类型的使用。

static Boolean IsDesignerAttachedProperty(XamlMember xamlMember)
{
    return xamlMember.IsAttachable &&
        xamlMember.PreferredXamlNamespace.Equals(c_sapNamespaceURI, StringComparison.OrdinalIgnoreCase);
}

const String c_sapNamespaceURI = "http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation";

// The next item of interest is the constructor, where the utilization of the inner XAML writer is seen.
public ViewStateCleaningWriter(XamlWriter innerWriter)
{
    this.InnerWriter = innerWriter;
    this.MemberStack = new Stack<XamlMember>();
}

XamlWriter InnerWriter {get; set; }
Stack<XamlMember> MemberStack {get; set; }

另外,此操作还将创建在遍历节点流时使用的 XAML 成员的堆栈。 此示例的剩余工作主要包含在 WriteStartMember 方法中。

public override void WriteStartMember(XamlMember xamlMember)
{
    MemberStack.Push(xamlMember);

    if (IsDesignerAttachedProperty(xamlMember))
    {
        m_attachedPropertyDepth++;
    }

    if (m_attachedPropertyDepth > 0)
    {
        return;
    }

    InnerWriter.WriteStartMember(xamlMember);
}

然后,后续方法将检查它们是否仍包含在视图状态容器中,如果是这样,则返回且不在编写器堆栈中向下传递节点。

public override void WriteValue(Object value)
{
    if (m_attachedPropertyDepth > 0)
    {
        return;
    }

    InnerWriter.WriteValue(value);
}

若要使用自定义 XAML 编写器,则必须在 XAML 编写器堆栈中将其链接起来。 下面的代码演示如何执行此操作。

XmlWriterSettings writerSettings = new XmlWriterSettings {  Indent = true };
XmlWriter xmlWriter = XmlWriter.Create(File.OpenWrite(args[1]), writerSettings);
XamlXmlWriter xamlWriter = new XamlXmlWriter(xmlWriter, new XamlSchemaContext());
XamlServices.Save(new ViewStateCleaningWriter(ActivityXamlServices.CreateBuilderWriter(xamlWriter)), ab);

使用此示例

  1. 使用 Visual Studio 打开 ViewStateCleaningWriter.sln 解决方案文件。

  2. 打开命令提示符,导航到生成 ViewStageCleaningWriter.exe 的目录。

  3. 在 Workflow1.xaml 文件上运行 ViewStateCleaningWriter.exe。

    下面的示例演示了可执行文件的语法。

    ViewStateCleaningWriter.exe [input file] [output file]
    

    这会将 XAML 文件输出到 [outfile],已移除其所有视图状态信息。

注意

已为 Sequence 工作流移除大量虚拟化提示。 这将导致设计器在下次加载时重新计算布局。 在对 Flowchart 使用此示例时,将移除所有定位和行路由信息,并且在后续加载到设计器中时,所有活动将在屏幕左侧堆叠。

创建与此示例一起使用的示例 XAML 文件

  1. 打开“Visual Studio”。

  2. 创建新的工作流控制台应用程序。

  3. 将几个活动拖放到画布上。

  4. 保存工作流 XAML 文件。

  5. 检测 XAML 文件以查看视图状态附加属性。