创建控件的透明部分以查看其下方的控件

2023-12-12

我已经修改了超级上下文菜单条在 CodeProject 找到的,可以满足我的一些项目需求。我将其用作地图标记的工具提示GMap.NET 地图控件。下面是它的示例:

enter image description here

我想做的就是通过让它看起来更像一个泡沫来稍微美化一下。类似于旧的 Google 地图样式工具提示:

enter image description here

我花了一些时间搜索控件透明度,我知道这不是一件容易的事情。这个SO问题特别说明了这一点。

我考虑过重写OnPaint的方法SuperContextMenuStrip绘制位于下面的 GMap.NET 控件的背景SuperContextMenuStrip,但如果标记挂在 GMap.NET 控件上,即使这样也会失败:

enter image description here

创建我正在寻找的透明度类型的正确方法是什么?


在 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);
       }

然后,您可以将控件的区域设置为 CreateRegion 方法返回的区域。

this.Region = CreateRegion(YourMaskBitmap);

删除透明度:

this.Region = new Region();

从上面的代码中您可能可以看出,创建区域在资源方面是昂贵的。如果您需要多次使用它们,我建议将区域保存在变量中。如果您以这种方式使用缓存区域,您很快就会遇到另一个问题。该分配第一次会起作用,但在后续调用中您会收到 ObjectDisposeException。

使用reflector进行一些调查会发现 Region 属性的 set 访问器中存在以下代码:

         this.Properties.SetObject(PropRegion, value);
            if (region != null)
            {
                region.Dispose();
            }

Region对象在使用后被丢弃! 幸运的是,区域是可克隆的,您需要做的就是分配一个克隆来保留区域对象:

private Region _myRegion = null;
private void SomeMethod() {
    _myRegion = CreateRegion(YourMaskBitmap);            
}

private void SomeOtherMethod() {
    this.Region = _myRegion.Clone();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建控件的透明部分以查看其下方的控件 的相关文章

  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何读取扩展文件属性/文件元数据

    因此 我按照教程使用 ASP net core 将文件 上传 到本地路径 这是代码 public IActionResult About IList
  • 如何从画布中删除路径区域(Android)

    我需要裁剪角落ImageView 不要将它们弄圆 而是擦除每个角上的三角形 似乎唯一的方法就是覆盖onDraw方法并使用从画布上删除这些区域Path 问题是我没有纯色背景 所以我需要擦除这些区域 但不要用某种颜色填充它们 我为此使用以下代码
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐