如何在保持控件可见的同时为ac#表单添加透明度?

Che*_*ese 7 c# graphics transparency image winforms

更新:我花了几天时间搞乱了透明度的东西.我今晚又开始搞砸了.我使用Hans Passant的解决方案得到了一个新结果: 新结果http://img3.imageshack.us/img3/4265/icontransp.jpg http://img3.imageshack.us/img3/4265/icontransp.jpg

Passant的解决方案确实解决了透明背景渐变的问题.但是,我仍然遇到问题,我的图标中的透明颜色与表单的BackColor混合.您可以在上图中看到图标各个部分周围的紫红色.

原始内容:

我已经在这几个小时了,而且我运气不好.我已经搞砸了Control.Region,Form.TransparencyKey,Form.Opacity以及其他一些带有一些时髦效果的随机事物.

最近我一直在尝试自定义我的桌面,并决定搞乱应用程序码头.在看到Mac Dock和一些第三方Windows实现提供的内容之后,我决定构建自己的.

最终我想继续使用Win32 API.目前我只想使用尽可能多的C#和.Net框架功能.

我想在这个应用程序中做一些事情:

  • 显示带有渐变背景的表单/菜单.
  • 允许表单/菜单具有透明度,同时保持图标不透明.
  • 显示包含透明背景的图标.
  • 菜单和图标应该能够接收与鼠标相关的事件(悬停,离开,点击,dragover,dragdrop和其他一些事件).

这就是我拍摄的效果: 期望的效果http://img207.imageshack.us/img207/5716/desired.jpg http://img207.imageshack.us/img207/5716/desired.jpg

此图像显示了我想要实现的视觉效果.这是我为一个名为Rainmeter的程序制作的皮肤.图像显示了皮肤后面的Notepad ++,其中一些皮肤文件在编辑器中打开.菜单是透明的,但图标保持不透明.

我的方法:

使用表单作为菜单似乎是我合乎逻辑的首选.我对事件有基本的了解.我不太确定如何创建自己的点击事件,因此表单可以使事件处理更容易.我考虑了一些图标选项.我决定使用PictureBoxes作为图标,因为它们可以保存图像并接收事件.

一旦我完成了菜单中所有结构逻辑的代码,我就开始玩它来尝试获得我想要的视觉效果.Form.Opacity影响了表单上所有内容的透明度.由于我希望图标完全不透明,所以我独自留下了这个属性.我尝试将BackColor设置为Color.Transparent,但这会产生错误.我玩了几个组合...... 组合效果http://img204.imageshack.us/img204/757/effectsi.jpg http://img204.imageshack.us/img204/757/effectsi.jpg

我使用Drawing2D.LinearGradientBrush将渐变绘制到位图中.然后将此位图放置为Form.BackgroundImage或PictureBox.Image.如果使用,PictureBox的大小将覆盖整个表单并发送到后面.

我注意到一些Form.BackgroundColor会与我的图标轮廓混在一起.图标沿边缘具有透明度,使外观更加平滑.由于图标正在拾取Form的BackgroundColor,这使我认为PictureBoxes在图标加载到表单时创建新图像.然后,当图像的半透明部分与表单后面的任何颜色合并时,它们将与Form的BackgroundColor合并.

白色桌面效果http://img838.imageshack.us/img838/8299/whitedesktop.jpg http://img838.imageshack.us/img838/8299/whitedesktop.jpg

在此图像中,即使Form的紫红色现在完全透明,您也可以看到图标中存在的紫红色.我忘了指出在每种情况下使用相同的绿色到黄色渐变,Alpha值为150.在渐变看起来不是绿色的图像中,这是因为透明颜色与紫红色背景混合.

我不确定从这里做什么.如果我能以某种方式使表单完全透明,我觉得我能得到我想要的东西.我也在想我可能只是绘制图标而不是使用PictureBoxes.那么问题是设置图标以接收鼠标事件.(我从未做过自己的事件,我认为它会涉及一些Win32 API调用.)

我可以用PictureBoxes做些什么来获得我想要的效果吗?无论哪种情况,我都会接受任何有关我正在努力实现的整体效果的想法或建议.

Han*_*ant 13

在Winforms中这很容易做到.你需要的是两种形式的三明治.底部应提供透明渐变背景,顶部应绘制图标并处理鼠标单击.一些示例代码:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        this.TopMost = true;
        this.FormBorderStyle = FormBorderStyle.None;
        this.TransparencyKey = this.BackColor = Color.Fuchsia;
        this.Opacity = 0.3;
        var overlay = new Form();
        overlay.FormBorderStyle = FormBorderStyle.None;
        overlay.TransparencyKey = overlay.BackColor = Color.Fuchsia;
        overlay.StartPosition = FormStartPosition.Manual;
        overlay.Location = this.Location;
        overlay.MouseDown += HandleIconClick;
        this.Resize += delegate { overlay.Size = this.Size; };
        this.LocationChanged += delegate { overlay.Location = this.Location; };
        overlay.Paint += PaintIcons;
        this.Paint += PaintBackground;
        this.Load += delegate { overlay.Show(this); };
    }
    private void PaintBackground(object sender, PaintEventArgs e) {
        var rc = new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height);
        using (var br = new LinearGradientBrush(rc, Color.Gainsboro, Color.Yellow, 0f)) {
            e.Graphics.FillRectangle(br, rc);
        }
    }
    private void PaintIcons(object sender, PaintEventArgs e) {
        e.Graphics.DrawIcon(Properties.Resources.ExampleIcon1, 50, 30);
        // etc...
    }
    void HandleIconClick(object sender, MouseEventArgs e) {
        // TODO
    }
}
Run Code Online (Sandbox Code Playgroud)

我选择的颜色和图标看起来像这样:

在此输入图像描述

  • 不要使用PictureBoxes.它们只是不必要的并且弄乱了图形效果.只需使用Paint事件绘制您想要的任何内容,如片段中所示.您唯一需要做的就是检测它们是否被点击.在HandleIconClick方法中,您知道在哪里绘制图标,因此您还知道e.Location何时与图标重叠.关键是要停止认为一切都需要成为一种控制. (2认同)

Har*_*can 0

好吧,我有点迷失了,但从原始段落中的描述来看,我会确保背景矩形不是图片框的视觉父级。使用Panel.Zindex 将它们设为重叠的兄弟姐妹,并将图片框放在前面。

然后你可以只改变矩形的不透明度,而不影响图标。还要确保图标源图像文件具有透明背景。

我认为应该有效。