如何在保持控件可见的同时向 c# 表单添加透明度? [英] How can I add transparency to a c# form while keeping controls visible?

查看:20
本文介绍了如何在保持控件可见的同时向 c# 表单添加透明度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<块引用>

更新:几天来,我暂停了与透明度相关的工作.今晚我又开始搞砸了.我使用 Hans Passant 的解决方案得到了一个新结果:http://img838.imageshack.us/img838/8299/whitedesktop.jpg

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

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

我还能用图片框做些什么来获得我想要的效果吗?无论是哪种情况,对于我想要达到的整体效果,我都愿意接受任何想法或建议.

解决方案

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

public partial class Form1 : Form {公共表格1(){初始化组件();this.TopMost = true;this.FormBorderStyle = FormBorderStyle.None;this.TransparencyKey = this.BackColor = Color.Fuchsia;this.Opacity = 0.3;var 覆盖 = 新表单();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);};}私有无效PaintBackground(对象发送者,PaintEventArgs e){var rc = new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height);使用 (var br = new LinearGradientBrush(rc, Color.Gainsboro, Color.Yellow, 0f)) {e.Graphics.FillRectangle(br, rc);}}私有无效PaintIcons(对象发送者,PaintEventArgs e){e.Graphics.DrawIcon(Properties.Resources.ExampleIcon1, 50, 30);//等等...}void HandleIconClick(对象发送者,MouseEventArgs e){//去做}}

我选择的颜色和图标有点随机,看起来像这样:

UPDATE: I took a break from messing with the transparency stuff for a few days. I started messing with it again tonight. I got a new result using Hans Passant's solution: http://img3.imageshack.us/img3/4265/icontransp.jpg

Passant's solution does solve the issue of the transparent background gradient. However, I'm still running into the problem with the transparent colors in my icon blending with the form's BackColor. You can see the fuchsia around various parts of the icon in the above image.

ORIGINAL CONTENT:

I've been going at this for several hours now, and I haven't had much luck. I've messed with Control.Region, Form.TransparencyKey, Form.Opacity, and a couple other random things with some funky effects.

Lately I've been trying to customize my desktop and decided to mess with Application Docks. After seeing what the Mac dock and a few third-party Windows implementations had to offer, I decided I wanted to build my own.

Eventually I want to move on to using the Win32 API. For now I just want to get something working using as much C# and .Net framework capabilities as possible.

There are a few things I want to be able to do in this application:

  • Display a form/menu with a gradient background.
  • Allow the form/menu to have transparency while keeping icons opaque.
  • Display icons that contain transparent backgrounds.
  • The Menu and Icons should be able to receive mouse-related events (hover, leave, click, dragover, dragdrop, and a few others).

This is the effect I'm shooting for: http://img207.imageshack.us/img207/5716/desired.jpg

This image shows the visual effects I'm trying to achieve. This was a skin I made for a program called Rainmeter. The image shows Notepad++ behind the skin with a few of the skin's files open in the editor. The menu is transparent, but the icons remain opaque.

My Approach:

Using a Form to act as the menu seemed like a logical first choice to me. I have a basic understanding of events. I'm not quite sure how to create my own click events, so a form would make working with events a tad easier. I considered a few options for the icons. I decided I'd use PictureBoxes for the icons, since they can hold images and receive events.

Once I finished the code for all the structural logic of my menu, I started playing around with it to try to get the visual effect I wanted. Form.Opacity affected the transparency of everything on the form. Since I want the icons to be fully opaque, I left this property alone. I tried setting the BackColor to Color.Transparent, but that gives an error. I played around with a few combinations... http://img204.imageshack.us/img204/757/effectsi.jpg

I drew the gradient with a Drawing2D.LinearGradientBrush into a Bitmap. This Bitmap was then placed as the Form.BackgroundImage or as a PictureBox.Image. If used, the PictureBox was sized to cover the entire Form and sent to the back.

I noticed that some of the Form.BackgroundColor would be mixed in with the outlines of my icons. The icons have transparency along the edges for a smoother appearance. Since the icons are picking up the Form's BackgroundColor, this makes me think that the PictureBoxes are creating new images when the icons are loaded into the form. The semi-transparent portions of the image are then merged with the Form's BackgroundColor when they should merge with whatever colors are behind the form.

http://img838.imageshack.us/img838/8299/whitedesktop.jpg

In this image you can see the Fuchsia existing in the icons even though the Form's Fuchsia color is now completely transparent. I forgot to point out that the same green to yellow gradient with an Alpha value of 150 was used in every case. In the images where the gradient doesn't look green, it's because the transparent colors are blending with the Fuchsia background.

I'm not really sure what to do from here. I feel like I could get what I want if I could somehow make the Form alone completely transparent. I was also thinking I may have better luck just drawing the icons instead of using PictureBoxes. The problem then would be setting up the icons to receive mouse events. (I've never made my own events, and I think it would involved some Win32 API calls.)

Is there something else I can do with the PictureBoxes to get the effect I want? Whichever the case, I'm open to any ideas or suggestions for the overall effect I'm trying to achieve.

解决方案

This is pretty easy to do in Winforms. What you need is a sandwich of two forms. The bottom one should provide the transparent gradient background, the top one should draw the icons and handle mouse clicks. Some sample code:

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
    }
}

Which looks like this with the somewhat random colors and icon I selected:

这篇关于如何在保持控件可见的同时向 c# 表单添加透明度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆