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

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

讨论

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

若要创建自定义 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 文件以查看视图状态附加属性。