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

标签 c# winforms image graphics transparency

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: new result 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.


原创内容:
我已经这样做了几个小时了,我没有太多的运气。我弄乱了 Control.Region、Form.TransparencyKey、Form.Opacity 和其他一些带有一些时髦效果的随机事物。
最近我一直在尝试自定义我的桌面并决定弄乱应用程序坞。在看到 Mac Dock 和一些第三方 Windows 实现所提供的功能后,我决定自己构建。
最终我想继续使用 Win32 API。现在,我只想使用尽可能多的 C# 和 .Net 框架功能来做一些事情。
我希望在这个应用程序中能够做一些事情:
  • 显示带有渐变背景的表单/菜单。
  • 允许表单/菜单具有透明度,同时保持图标不透明。
  • 显示包含透明背景的图标。
  • 菜单和图标应该能够接收与鼠标相关的事件(悬停、离开、单击、拖动、拖放等)。

  • 这是我要拍摄的效果:
    Desired Effect
    http://img207.imageshack.us/img207/5716/desired.jpg
    这张图片显示了我想要达到的视觉效果。这是我为名为 Rainmeter 的程序制作的皮肤。该图像显示了皮肤后面的 Notepad++,其中一些皮肤文件在编辑器中打开。菜单是透明的,但图标保持不透明。
    我的方法:
    使用表单作为菜单对我来说似乎是合乎逻辑的首选。我对事件有基本的了解。我不太确定如何创建我自己的点击事件,所以表单会使处理事件变得更容易一些。我考虑了一些图标选项。我决定将 PictureBoxes 用于图标,因为它们可以保存图像并接收事件。
    一旦我完成了菜单的所有结构逻辑的代码,我就开始使用它来尝试获得我想要的视觉效果。 Form.Opacity 影响表单上所有内容的透明度。因为我希望图标完全不透明,所以我不理会这个属性。我尝试将 BackColor 设置为 Color.Transparent,但这会产生错误。我玩了几个组合...
    Combination Effects
    http://img204.imageshack.us/img204/757/effectsi.jpg
    我用 Drawing2D.LinearGradientBrush 将渐变绘制到位图中。然后将此位图作为 Form.BackgroundImage 或 PictureBox.Image 放置。如果使用,PictureBox 的大小将覆盖整个表单并发送到后面。
    我注意到一些 Form.BackgroundColor 会与我的图标的轮廓混合在一起。图标沿边缘具有透明度,以使外观更平滑。由于图标正在获取表单的 BackgroundColor,这让我认为当图标加载到表单中时 PictureBoxes 正在创建新图像。当图像的半透明部分应该与表单后面的任何颜色合并时,它们会与表单的 BackgroundColor 合并。
    effect with white desktop
    http://img838.imageshack.us/img838/8299/whitedesktop.jpg
    在此图像中,您可以看到图标中存在紫红色,即使表单的紫红色现在完全透明。我忘了指出在每种情况下都使用了相同的绿色到黄色渐变,Alpha 值为 150。在渐变看起来不是绿色的图像中,这是因为透明颜色与紫红色背景混合。
    我真的不知道从这里做什么。我觉得如果我能以某种方式使表单完全透明,我就能得到我想要的东西。我还想我可能会更好地绘制图标而不是使用 PictureBoxes。那么问题将是设置图标以接收鼠标事件。 (我从来没有自己的事件,我认为它会涉及一些 Win32 API 调用。)
    我还能用 PictureBoxes 做些什么来获得我想要的效果吗?无论哪种情况,对于我想要达到的整体效果,我都愿意接受任何想法或建议。

    最佳答案

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

    看起来像这样,我选择了一些随机的颜色和图标:

    enter image description here

    关于c# - 如何在保持控件可见的同时向 c# 表单添加透明度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10266920/

    相关文章:

    c# - 使用 .Net Core 2 和 Moq,如何设置 HTTP 上下文来伪造身份验证?

    c# - 为什么 Task.ContinueWith 在此单元测试中执行失败?

    html - 如何使用 css 重新定位具有线性渐变的图像?

    c# - 确定应用程序是 WinForms 还是 WebForms

    c# - 如何使用 Xaml 将列表绑定(bind)到 WPF TreeView ?

    javascript - jQuery datepicker - knockout 绑定(bind)设置初始日期

    c# - 如何使用 Winforms 的列表框控件中已经存在的值填充 List<String>

    C# 如何在文本框具有焦点时通过按 Enter 来单击按钮?

    Android:在风景模式下拍摄的照片力

    c# - 在图片框上绘图时位置错误