65.9K
CodeProject 正在变化。 阅读更多。
Home

创建一个透明的 MDI 父窗体

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.07/5 (7投票s)

2010年1月27日

CPOL

3分钟阅读

viewsIcon

48696

downloadIcon

2824

一个如何制作自定义形状(通过透明度实现)的 MDI 容器窗体的指南。

引言

本文讨论了一种创建非矩形 MDI 父窗体的方法:透明键(Transparency Key)。

背景

本文基于我看到的一些问题:当我们设置 FormIsMdiContaner 属性为 true 时,背景颜色无法更改!窗体无法透明……所以,我们开始吧。

Using the Code

那么,这是怎么实现的呢?很简单。

首先,不要将 FormIsMdiContaner 属性设置为 true!只需创建一个项目,并在 Form_Load 事件处理程序中执行以下操作:

this.TransparencyKey = Color.FromArgb(255, 220, 33, 55);
MdiClient Client = new MdiClient();
this.Controls.Add(Client);
Form Child = new Form();

Child.Size = new Size(100, 100);
Child.FormBorderStyle = FormBorderStyle.FixedDialog;
Child.StartPosition = FormStartPosition.CenterParent;
Child.MaximizeBox = false;
Child.MinimizeBox = false;

Child.MdiParent = this;
this.pictureBox1.Controls.Add(Child);

Child.Show();

那么,这是什么意思?

我们来逐行解释。首先,我们有一张图片(例如,一张支持透明色的 PNG 图片,就像源码中包含的 *Image.png*),其中窗体不需要的部分用特定颜色标记(这里我使用了 Adobe Photoshop,颜色对应的 RGB 值为:R = 220,G = 33,B = 55)。

所以,我们将它加载到一个 PictureBox 中,并将其放在 Form 上,将 PictureBoxDock 属性设置为 Fill。好了。现在,是时候重塑窗体了。

概念很简单:通过设置任何 .NET Framework Form 对象的 TransparencyKey 属性,它会将所有具有 TransparencyKey 颜色的像素更改为 TransparentColor 像素。这样,任何在该像素后面的东西都将可见,就像透过玻璃一样。

所以,在第一行,我们按需设置属性:

this.TransparencyKey = Color.FromArgb(255, 220, 33, 55);

(要使 MdiClient 本身透明,TransparencyKey 必须设置为此值而不是上面那个

this.TransparencyKey = Color.FromArgb(255, 171, 171, 171);

)

到目前为止,我们已经重塑了窗体。但请始终记住,这样只会改变窗体的外观,而不是它的区域!所以,它的 HeightWidth 等值与之前相同。

现在,我们创建一个 MdiClient 对象并将其放置在窗体上。当您将任何窗体的 IsMdiContainer 属性设置为 true 时,默认情况下,一个 MdiClient 对象将被添加到窗体中,并由它控制窗体的绘制和背景绘制事件。

(关于 MdiClient,Jacob Slusser 有一篇非常好的文章,供进一步阅读:Getting a "Handle" on the MDI Client。我建议您阅读一下!)

在这里,我们自己来完成这个操作:

MdiClient Client = new MdiClient();

this.Controls.Add(Client);

希望您现在已经明白了其中的窍门!如果还没有,没关系:我来解释一下。

这取决于将对象添加到窗体“Controls”集合的顺序。在这里,我们首先将 PictureBox 添加到集合中,然后再添加 MdiClient。但是,通过设置 IsMdiContainer 属性,Controls 集合中的第一个对象将是 MdiClient。因此,绘制事件将不会实现透明效果。

现在,创建子窗体并将其 MdiParent 属性设置为当前窗体。

Form Child = new Form();

Child.Size = new Size(100, 100);
Child.FormBorderStyle = FormBorderStyle.FixedDialog;
Child.StartPosition = FormStartPosition.CenterParent;
Child.MaximizeBox = false;
Child.MinimizeBox = false;

Child.MdiParent = this;

但是,这样做还不够。如果您现在就调用 Show() 方法,您将看不到子窗体!这是为什么呢?

还记得那个窍门吗?“Controls”集合!您的子窗体将位于 PictureBox 的下方。我通过将子窗体添加到 PictureBoxControls 集合中来解决这个问题(尽管还有其他方法可以做到这一点)。

this.pictureBox1.Controls.Add(Child);

现在,通过调用 Show(),您将看到您的子窗体。

Child.Show();

完成!

请记住,父窗体的区域在使其透明之前与之后仍然是相同的!所以,子窗体可以移动到这个区域,甚至可以移动到透明区域。这有其自身的用途,所以我将保持现状。

待办事项(即将推出!):限制子窗体不能移动到非透明区域之外!;)

希望这能帮助到某人。

历史

  • 2010年1月27日:初次发布
  • 2010年1月27日:文章更新
© . All rights reserved.