我修改了CodeProject中的SuperContextMenuStrip以满足我的一些项目需求。我将它用作GMap.NET Map Control上地图标记的工具提示。以下是它的样子:
我想做的是让它看起来更像泡泡。与旧的Google Maps样式工具提示类似:
我花了一些时间搜索控制透明度,我知道这不是一件容易的事。 This SO question in particular illustrates that.
我考虑覆盖OnPaint
的{{1}}方法来绘制SuperContextMenuStrip
下面的GMap.NET控件的背景,但即使这样做也会失败标记悬挂在GMap.NET控件上:
创建我正在寻找的透明度类型的正确方法是什么?
答案 0 :(得分:3)
在Windows窗体中,您可以通过定义区域来实现透明度(或绘制不规则形状的窗口)。引用MSDN
窗口区域是窗口中像素的集合所在 操作系统允许绘图。
在您的情况下,您应该有一个位图,您将用作掩码。位图应至少有两种不同的颜色。其中一种颜色应代表您想要透明的控件部分。
然后您将创建一个这样的区域:
// this code assumes that the pixel 0, 0 (the pixel at the top, left corner)
// of the bitmap passed contains the color you wish to make transparent.
private static Region CreateRegion(Bitmap maskImage) {
Color mask = maskImage.GetPixel(0, 0);
GraphicsPath grapicsPath = new GraphicsPath();
for (int x = 0; x < maskImage.Width; x++) {
for (int y = 0; y < maskImage.Height; y++) {
if (!maskImage.GetPixel(x, y).Equals(mask)) {
grapicsPath.AddRectangle(new Rectangle(x, y, 1, 1));
}
}
}
return new Region(grapicsPath);
}
然后,您可以将控件的Region设置为CreateRegion方法返回的Region。
this.Region = CreateRegion(YourMaskBitmap);
删除透明度:
this.Region = new Region();
正如您可以从上面的代码中看出的那样,创建区域在资源方面是昂贵的。如果您需要多次使用它们,我建议在变量中保存区域。如果您以这种方式使用缓存区域,您很快就会遇到另一个问题。赋值将在第一次运行,但在后续调用时会出现ObjectDisposedException。
使用refrector进行一些调查会在Region Property的set访问器中显示以下代码:
this.Properties.SetObject(PropRegion, value);
if (region != null)
{
region.Dispose();
}
Region对象在使用后处理! 幸运的是,Region是可克隆的,保存Region对象所需要做的就是分配一个克隆:
private Region _myRegion = null;
private void SomeMethod() {
_myRegion = CreateRegion(YourMaskBitmap);
}
private void SomeOtherMethod() {
this.Region = _myRegion.Clone();
}