Forms树视图中节点类型和上下文操作的可扩展性的最佳方法

时间:2022-01-06 15:51:06

I'm working on a Visual Studio Add-in for Visual Studio 2008 that display a treeview that provides a view on content in a server product. The server product contains different types of nodes, and each node has its own type of context menu (right click menu).

我正在为Visual Studio 2008开发一个Visual Studio外接程序,它显示一个树视图,提供服务器产品中内容的视图。服务器产品包含不同类型的节点,每个节点都有自己的上下文菜单类型(右键菜单)。

For new types of nodes and the actions connected to a node I currently just add code two my project. I would like to disconnect my node types and the actions available on a node in such a few that I can add nodes and entries to to context menu with a plugin model. MEF would probably be a good candidate. Does anyone have a good idea on how to implement this in a simple and straightforward way, so that especially the plugin developer does not have to do a lot of plumbing?

对于新类型的节点和连接到节点的操作,我目前只需将代码添加到我的项目中。我想断开我的节点类型和节点上可用的操作,以便我可以使用插件模型将节点和条目添加到上下文菜单中。 MEF可能是一个很好的候选人。有没有人对如何以简单直接的方式实现它有一个好主意,所以特别是插件开发人员不需要做很多管道工作?

1 个解决方案

#1


I would provide a common library that both your code and the plugin libraries all link to (call this the Contract dependency). In there, define an interface for a node type, like INodeType. Also, consider implementing an AbstractNodeType in there that implements INodeType and provides some helpful properties that the plugin author can set in their constructor.

我将提供一个公共库,您的代码和插件库都链接到它(称为契约依赖项)。在那里,定义节点类型的接口,如INodeType。另外,考虑在那里实现一个实现INodeType的AbstractNodeType,并提供一些插件作者可以在其构造函数中设置的有用属性。

One of the properties of INodeType is a ContextMenu property that returns a windows forms context menu.

INodeType的一个属性是ContextMenu属性,它返回一个Windows窗体上下文菜单。

In your code make a property:

在你的代码中创建一个属性:

[Import("NodeTypes", typeof(INodeType))]
public IEnumerable<INodeType> extensionNodeTypes { get; set; }

You can just enumerate through that after you've composed.

你可以在编写完成后列举一下。

In the plugin code, they would declare new node types something like this (may not compile):

在插件代码中,他们会声明类似这样的新节点类型(可能无法编译):

[Export("NodeTypes", typeof(INodeType))]
public class SomeNodeType : AbstractNodeType
{
    public SomeNodeType()
    {
        this.ContextMenu = base.BuildContextMenu(/* ... */);
        /* etc. */
    }
    /* ... other custom logic ... */
}

I hope I didn't mess up the syntax, but that's the general idea.

我希望我没有弄乱语法,但这是一般的想法。

#1


I would provide a common library that both your code and the plugin libraries all link to (call this the Contract dependency). In there, define an interface for a node type, like INodeType. Also, consider implementing an AbstractNodeType in there that implements INodeType and provides some helpful properties that the plugin author can set in their constructor.

我将提供一个公共库,您的代码和插件库都链接到它(称为契约依赖项)。在那里,定义节点类型的接口,如INodeType。另外,考虑在那里实现一个实现INodeType的AbstractNodeType,并提供一些插件作者可以在其构造函数中设置的有用属性。

One of the properties of INodeType is a ContextMenu property that returns a windows forms context menu.

INodeType的一个属性是ContextMenu属性,它返回一个Windows窗体上下文菜单。

In your code make a property:

在你的代码中创建一个属性:

[Import("NodeTypes", typeof(INodeType))]
public IEnumerable<INodeType> extensionNodeTypes { get; set; }

You can just enumerate through that after you've composed.

你可以在编写完成后列举一下。

In the plugin code, they would declare new node types something like this (may not compile):

在插件代码中,他们会声明类似这样的新节点类型(可能无法编译):

[Export("NodeTypes", typeof(INodeType))]
public class SomeNodeType : AbstractNodeType
{
    public SomeNodeType()
    {
        this.ContextMenu = base.BuildContextMenu(/* ... */);
        /* etc. */
    }
    /* ... other custom logic ... */
}

I hope I didn't mess up the syntax, but that's the general idea.

我希望我没有弄乱语法,但这是一般的想法。