Visual Studio自定义XAML设计器

8
我有一个应用程序,在其中我使用XAML表示自己的自定义对象图。这与WPF / Silverlight对象模型非常不同(不用于UI设计),但是可以以有意义的方式可视化对象图。我想做的是添加Visual Studio的设计扩展,以可视化我的特定对象,但我一直在找此主题的信息。能否有人指点我正确方向?
我的主要目标是对当前XAML进行简单的可视反馈;我还没有达到需要设计师支持可视化编辑的阶段。如果有人感兴趣,这是一个模拟工业机械的工具;我使用XAML来定义机器的组件及其连接,但目前必须运行完整的模拟才能看到机器的外观。
3个回答

11
你需要创建一个Visual Studio扩展(vsix),可以解析文件并可视化内容。你有两个选项,一个是Visual Studio Add-In(插件),另一个是Visual Studio Package(扩展包)(有关详细差异请参见问题1139294)。前者稍微容易入手一些,但如果您未来想要编辑的话,我建议选择后者,因为它会给您更多的控制权。
首先下载用于创建Visual Studio扩展的SDK,也就是Visual Studio 2010 SP1 SDK。对于旧版本不带SP1的SDK,请单击这里
你需要熟悉创建Visual Studio扩展包的方法。若要了解Microsoft的教程,请参阅Walkthrough: Creating a VSPackage。如果你按照教程操作,你应该拥有触发菜单命令的自定义组件所需的所有东西。现在,你真正需要的只是一个可以解析/可视化你的自定义XAML的常规WPF组件。你还可能需要将自定义文件类型与你的组件关联起来。为此,你需要一个ProvideEditorExtensionAttribute
没有比示例更好的东西了,所以请看The IDE Sample Editor,顺便欣赏它的代码。从示例库中获取“Editor”组件。该组件可创建与您所需相似的小型文件编辑器自定义文件类型。将文件编辑器组件和相关的文件类型替换为您的编辑器即可完成大部分工作!


谢谢,这确实帮我找到了正确的方向。我的情况略有不同(因为我没有自定义文件格式;它仍然是*.xaml扩展名,仍然编译成一个类,同时带有一个支持代码文件,就像任何其他的xaml类一样)。不过,这仍然非常有用。 - Dan Bryant
是的,有趣的是,在 Silverlight 项目中,VS 知道如何以一种方式呈现 .xaml 文件,在 WPF 项目中,VS 则知道以另一种方式呈现它。也许还可以通过某些项目模板魔法来指定“对于项目类型 x,请使用 XAML 设计器”,等等... - BrainSlugs83

0

你要找的是ProvideXmlEditorChooserDesignerViewAttribute,虽然你必须以这种方式使用它才能使其正常工作,但它有点奇怪。 https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.modeling.shell.providexmleditorchooserdesignerviewattribute_properties.aspx

我刚刚在自己的扩展中让它工作了,而且非常容易(一旦你掌握了魔法公式)。从VS Extensibility示例“带工具箱的编辑器”(https://github.com/Microsoft/VSSDK-Extensibility-Samples/tree/master/Editor_With_Toolbox)开始,按照以下步骤进行:

  1. 将自定义文件扩展名从.tbx更改为.xaml。这并不太困难,主要是查找+替换.tbx为.xaml,并将tbx.tbx文件更改为xaml.xaml,并在解决方案中的每个文件中进行查找+替换。这将标记您的EditorFactory为提供.xaml文件的编辑器。
  2. 打开EditorPackage.cs并删除ProvideEditorExtension和ProvideEditorLogicalView属性。用这些属性替换它们(显然用实际字符串替换存根字符串)。

    [ProvideXmlEditorChooserDesignerView("UnimportantDesignerViewName", "xaml",
        LogicalViewID.Designer, 10000,
        DesignerLogicalViewEditor = typeof(EditorFactory),
        Namespace = "YourNamespace",
        MatchExtensionAndNamespace = true)]
    [ProvideXmlEditorChooserDesignerView("UnimportantDesignerViewName_Enforced", "xaml",
        LogicalViewID.Designer, 10001,
        DesignerLogicalViewEditor = typeof(EditorFactory))]
    [ProvideEditorLogicalView(typeof(EditorFactory), LogicalViewID.TextView)]
    [ProvideEditorLogicalView(typeof(EditorFactory), LogicalViewID.Code)]
    [ProvideEditorLogicalView(typeof(EditorFactory), LogicalViewID.Designer)]
    [ProvideEditorLogicalView(typeof(EditorFactory), LogicalViewID.Debugging)]
    
  3. 打开EditorFactory.cs并编辑CreateEditorInstance方法。在这里,您将打开由pszMkDocument文件路径参数指定的.xaml文件,并验证它是否属于您的文件(例如,它使用您的模式或其他内容)。如果是,则输出您的EditorFactory Guids并返回S_OK。如果不是(例如,如果它是WPF.xaml文件),则输出Guid.Empty并返回VS_E_UNSUPPORTEDFORMAT。

    string extension = System.IO.Path.GetExtension(pszMkDocument);
    if (extension.Equals(".xaml", StringComparison.OrdinalIgnoreCase))
    {
        using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(pszMkDocument))
        {
            reader.MoveToContent();
            if (reader.NodeType == System.Xml.XmlNodeType.Element)
            {
                if (reader.NamespaceURI.Equals("YourNamespace", StringComparison.OrdinalIgnoreCase))
                {
                    EditorPane newEditor = new EditorPane();
                    ppunkDocView = Marshal.GetIUnknownForObject(newEditor);
                    ppunkDocData = Marshal.GetIUnknownForObject(newEditor);
                    pbstrEditorCaption = "";
                    return VSConstants.S_OK;
                }
            }
        }
    }
    return VSConstants.VS_E_UNSUPPORTEDFORMAT;
    

我是通过 Avalonia GitHub 代码库 (https://github.com/AvaloniaUI/AvaloniaVS/blob/master/src/AvaloniaVS/Infrastructure/AvaloniaPackage.cs) 偶然发现了这个神奇的属性公式,非常感谢那些人为解决这个问题而付出的努力。我在 VS 2017 Community 中实现了它,对我来说工作得非常好。祝所有试图完成同样神秘任务的人好运。=)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接