熟悉VS SDK开发的请帮我解决一个问题

还想懒够 2012-04-05 11:53:46
当前我新建了一个基于Component类,并声明为IRootDesigner

现在出现的效果就是在VS设计模式时,可以出现一个带点的面板(那些点都是自己用双缓冲+GDI画的)

如下图所示:




现在出现的情况就是我想在设计面板中点击鼠标右键,弹出菜单后出现“查看代码”“粘贴”“属性”等操作,类似于WinForm设计时右键菜单。请问该如何实现。

注:现在我已安装好VS SDK 2008 SP1

以下附基于Component类的代码:

1. DesignPanel

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;

namespace eWhereThink.Workflow.Design
{
[Designer(typeof(DesignPanelDesigner), typeof(IRootDesigner))]
[Designer(typeof(ComponentDesigner))]
[ToolboxItem(false)]
public class DesignPanel : Component
{
public DesignPanel()
{

}

}
}


2. DesignPanelDesigner
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace eWhereThink.Workflow.Design
{
public class DesignPanelDesigner : ComponentDocumentDesigner, IRootDesigner
{
DesignControl _rootViewControl;

public DesignPanelDesigner()
{

}

public object GetView(ViewTechnology technology)
{
_rootViewControl = new DesignControl(this);
return _rootViewControl;
}

public ViewTechnology[] SupportedTechnologies
{
get
{
return new ViewTechnology[] { ViewTechnology.Default };
}
}

protected override bool GetToolSupported(ToolboxItem tool)
{
MessageBox.Show(tool.TypeName);
return true;
}

public void ToolPicked(ToolboxItem tool)
{
MessageBox.Show(tool.TypeName + " ToolPicked");
}
}
}


3. DesignControl
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace eWhereThink.Workflow.Design
{
[ToolboxItem(false)]
public class DesignControl : ScrollableControl
{
private DesignPanelDesigner _rootDesigner;
private IContainer components;
private Hashtable _componentInfoTable;

public DesignControl(DesignPanelDesigner rootDesigner)
{
InitializeComponent();
_rootDesigner = rootDesigner;
_componentInfoTable = new Hashtable();

SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);

this.Invalidate();
}

private void InitializeComponent()
{
this.SuspendLayout();
//
// DesignControl
//
this.Paint += new System.Windows.Forms.PaintEventHandler(this.DesignControl_Paint);
this.ResumeLayout(false);

}

private void DesignControl_Paint(object sender, PaintEventArgs e)
{
float fZoom = 1F;

Size size = new Size();
size.Width = Math.Max(this.Width, this.AutoScrollMinSize.Width);
size.Height = Math.Max(this.Height, this.AutoScrollMinSize.Height);

Bitmap bmp = new Bitmap(size.Width, size.Height);
Graphics g = Graphics.FromImage(bmp);
Color selectColor = Color.FromArgb(102, 102, 255);
Brush selectBrush = new SolidBrush(selectColor);
try
{
g.SmoothingMode = SmoothingMode.HighQuality; //高质量
g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量

//画点
for (int iX = (int)(10 * fZoom); iX < bmp.Width; iX += (int)(10 * fZoom))
{
for (int iY = (int)(10 * fZoom); iY < bmp.Height; iY += (int)(10 * fZoom))
{
bmp.SetPixel(iX, iY, Color.Black);
}
}
e.Graphics.DrawImage(bmp, 0 - this.HorizontalScroll.Value, 0 - this.VerticalScroll.Value);
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
finally
{
selectBrush.Dispose();
g.Dispose();
bmp.Dispose();
}

}
}
}



如果新建一个类是继承于DesignPanel的,就可以看到设计时面板的状况了


谢谢!
...全文
498 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
还想懒够 2012-04-07
  • 打赏
  • 举报
回复
其实想明白了也挺简单的

首先进入了一个误区就是老在想着继承了某个接口就会出现那种菜单
第二个误区就是忽略了SDK的作用,误认为在Designer中就可以主动往VS IDE中注册菜单
还想懒够 2012-04-07
  • 打赏
  • 举报
回复
上述代码是在基于VS2008 SDK Sample-IDE-C# Sample XMLTreeEditor基础上更改的,详情可参阅那部分源代码


在Designer文件中加入以下代码

DesignControl _rootViewControl;
IMenuCommandService mcs;

public DesignPanelDesigner()
{
_rootViewControl = new DesignControl(this);
_rootViewControl.MouseUp += new MouseEventHandler(_rootViewControl_MouseUp);
}

void _rootViewControl_MouseUp(object sender, MouseEventArgs e)
{
mcs = (IMenuCommandService)this.GetService(typeof(IMenuCommandService));
if (mcs != null)
{
Point screenCoordinates = this._rootViewControl.PointToScreen(e.Location);

mcs.ShowContextMenu(new CommandID(new Guid("94c4438f-fe64-47d6-a0d9-fdf468448fac"), 0x0001), screenCoordinates.X, screenCoordinates.Y);
}
}

还想懒够 2012-04-07
  • 打赏
  • 举报
回复
1. 创建一个Integration Package,主要目的是为了注册菜单,相应的vsct文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" >
<Extern href="stdidcmd.h"/>
<Extern href="vsshlids.h"/>
<Extern href="msobtnid.h"/>
<Extern href="virtkeys.h"/>
<Commands package="guideWhereThink_Workflow_VS2008Pkg" >
<Menus>
<Menu guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDM_CONTEXT" priority="0x0000" type="Context">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="0"/>
<Strings>
<ButtonText>Workflow Designer</ButtonText>
<CommandName>Workflow Designer</CommandName>
</Strings>
</Menu>
</Menus>
<Groups>
<Group guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_VIEWCODE" priority="0x0100">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDM_CONTEXT"/>
</Group>
<Group guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_CLIPBOARD" priority="0x0200">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDM_CONTEXT"/>
</Group>
<Group guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_PROPERTY" priority="0x0300">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDM_CONTEXT"/>
</Group>
</Groups>
</Commands>
<CommandPlacements>
<CommandPlacement guid="guidVSStd97" id="cmdidViewCode" priority="0x0001">
<Parent guid="guidSHLMainMenu" id="IDG_VS_CODEWIN_LANGUAGE"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidViewCode" priority="0x0000">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_VIEWCODE"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidCut" priority="0x0001">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_CLIPBOARD"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidCopy" priority="0x0010">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_CLIPBOARD"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidPaste" priority="0x0020">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_CLIPBOARD"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidDelete" priority="0x0030">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_CLIPBOARD"/>
</CommandPlacement>
<CommandPlacement guid="guidVSStd97" id="cmdidPropSheetOrProperties" priority="0x0001">
<Parent guid="guideWhereThink_Workflow_VS2008CmdSet" id="IDG_PROPERTY"/>
</CommandPlacement>
</CommandPlacements>
<UsedCommands>
<!-- CMDUSED_SECTION -->
<UsedCommand guid="guidVSStd97" id="cmdidCut"/>
<UsedCommand guid="guidVSStd97" id="cmdidCopy"/>
<UsedCommand guid="guidVSStd97" id="cmdidPaste"/>
<UsedCommand guid="guidVSStd97" id="cmdidDelete"/>
<UsedCommand guid="guidVSStd97" id="cmdidPropSheetOrProperties"/>
</UsedCommands>
<Symbols>
<GuidSymbol name="guideWhereThink_Workflow_VS2008Pkg" value="{9afe836b-48b9-4201-a7ab-7569bda7917b}"></GuidSymbol>
<GuidSymbol name="guideWhereThink_Workflow_VS2008CmdSet" value="{94c4438f-fe64-47d6-a0d9-fdf468448fac}">
<IDSymbol name="IDM_CONTEXT" value="0x0001"/>
<IDSymbol name="IDG_VIEWCODE" value="0x1000"/>
<IDSymbol name="IDG_CLIPBOARD" value="0x1001"/>
<IDSymbol name="IDG_PROPERTY" value="0x1002"/>
</GuidSymbol>
</Symbols>
</CommandTable>


注意需要在Package类前加入声明,以及手动更改项目文件中的VSCTCompile属性
hetengfei_ 2012-04-07
  • 打赏
  • 举报
回复
想看看最后的[解决方案] 如何?
有看楼主贴出代码。
hetengfei_ 2012-04-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
我想知道红色标题是怎么发出来的。。。
[/Quote]
我也想知道,我还想知到绿的黄的标题。
还想懒够 2012-04-07
  • 打赏
  • 举报
回复
搞定了,效果如下,稍后公布解决方案:

还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
加我的QQ。我们有一个vs sdk开发群。专门搞这个的。
[/Quote]

已加了QQ了,谢谢!
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
有点不明白,你自己的组件,拖放到ide中,不是就有那些菜单了吗
[/Quote]

要在设计模式下弹出菜单,这个需要动用Visual Studio SDK了,并不像常规的处理方式一样。
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
我想知道红色标题是怎么发出来的。。。
[/Quote]

呵,我也想知道
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]
你看一下。vs sdk的demo里面有你要的加菜单的。
以前弄过这个东西太久了。vs2008比vs2005要简单的多了。听说vs2010更简单了。
[/Quote]

要不是要引用一些集成于IDE的菜单,如“查看代码”“剪切”“复制”“粘贴”,我实在的不想去集成IDE写菜单了。

微软咋就不定义一个简单一点的文件结构来呢。。。
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]
你看一下。vs sdk的demo里面有你要的加菜单的。
以前弄过这个东西太久了。vs2008比vs2005要简单的多了。听说vs2010更简单了。
[/Quote]

粗略看了一下,10>08>05,但终归那个vsct文件实在的太恶心
足球中国 2012-04-06
  • 打赏
  • 举报
回复
你看一下。vs sdk的demo里面有你要的加菜单的。
以前弄过这个东西太久了。vs2008比vs2005要简单的多了。听说vs2010更简单了。
足球中国 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

有点不明白,你自己的组件,拖放到ide中,不是就有那些菜单了吗
[/Quote]
这个是vs sdk 不是fw sdk。两个不是一个东西。
vs sdk只是针对vs2008系统进行扩展开发的。我那时搞的主要vs2005 。只是个破配置文件就搞了好几天。
足球中国 2012-04-06
  • 打赏
  • 举报
回复
加我的QQ。我们有一个vs sdk开发群。专门搞这个的。
冰镇宝贝321 2012-04-06
  • 打赏
  • 举报
回复
学习。。。。说真的 这个VS最笨的拖控件不就行了嘛 怎么出现这么奇怪的。。。。不明白
边城的刀声 2012-04-06
  • 打赏
  • 举报
回复
真不懂,关注
bdmh 2012-04-06
  • 打赏
  • 举报
回复
有点不明白,你自己的组件,拖放到ide中,不是就有那些菜单了吗
orochiheart 2012-04-06
  • 打赏
  • 举报
回复
我想知道红色标题是怎么发出来的。。。
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
经过一下午的琢磨,大概有了思路

1. 建立vsct文件,往VS2008里面注册一个ContextMenu
2. 在DesignerControl里面设置ShowContextMenu即可


先尝试一下
还想懒够 2012-04-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
这个是不是在给VS增加功能啊,不知道意义何在。
[/Quote]

一部分是在原有的基础上进行拓展,比如说继承Component来设计一个自定义的设计面板,非常类似于Windows Workflow的设计模式下的东西

可以参考这个:
http://windowsclient.net/articles/shapedesigner.aspx


另外一部分就是需要在VS进行设计时,点击鼠标右键,弹出VS中的常规右键菜单,如下图所示:



现在麻烦的就是如何设置VS菜单的问题

实际上我还有一个麻烦,就是如何使这个编辑器打开后,自动出现VS一级菜单,如WinForm进入设计模式,那么在VS的一级菜单中就会出现“格式”菜单,当进入到代码模式时,这个格式菜单会自动消失。但这个菜单仅只针对我当前这个设计器。
加载更多回复(3)

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧