创建一个透明的 MDI 父窗体
一个如何制作自定义形状(通过透明度实现)的 MDI 容器窗体的指南。
引言
本文讨论了一种创建非矩形 MDI 父窗体的方法:透明键(Transparency Key)。
背景
本文基于我看到的一些问题:当我们设置 Form
的 IsMdiContaner
属性为 true
时,背景颜色无法更改!窗体无法透明……所以,我们开始吧。
Using the Code
那么,这是怎么实现的呢?很简单。
首先,不要将 Form
的 IsMdiContaner
属性设置为 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
上,将 PictureBox
的 Dock
属性设置为 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);
)
到目前为止,我们已经重塑了窗体。但请始终记住,这样只会改变窗体的外观,而不是它的区域!所以,它的 Height
、Width
等值与之前相同。
现在,我们创建一个 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
的下方。我通过将子窗体添加到 PictureBox
的 Controls
集合中来解决这个问题(尽管还有其他方法可以做到这一点)。
this.pictureBox1.Controls.Add(Child);
现在,通过调用 Show()
,您将看到您的子窗体。
Child.Show();
完成!
请记住,父窗体的区域在使其透明之前与之后仍然是相同的!所以,子窗体可以移动到这个区域,甚至可以移动到透明区域。这有其自身的用途,所以我将保持现状。
待办事项(即将推出!):限制子窗体不能移动到非透明区域之外!;)
希望这能帮助到某人。
历史
- 2010年1月27日:初次发布
- 2010年1月27日:文章更新