c# - C# .NET 3.5 WinForms 部分透明?

标签 c# .net winforms drawing transparency

我正在制作一个 .NET 3.5 应用程序,其表单可以绘制部分透明的黑色背景。我重写 OnPaintBackground 来完成此任务:

protected override void OnPaintBackground( PaintEventArgs e )
{
    using ( Brush brush = new SolidBrush( Color.FromArgb( 155, Color.Black ) ) )
    {
        e.Graphics.FillRectangle( brush, e.ClipRectangle );
    } 
}

它可以工作,但有时窗体会在不清除屏幕的情况下绘制自身,从而使透明度比应有的颜色更暗。我尝试过使用 Graphics.Flush() 和 Graphics.Clear() ,但它要么没有帮助,要么完全消除了透明度。有什么建议吗?

编辑: 下面是它的样子,在左侧启动应用程序后,在右侧表单重新绘制几次(响应从一个控件切换到另一个控件)之后:

Transparency Issue http://www.quicksnapper.com/files/5085/17725729384A10347269148_m.png

编辑 2: 今天早上我尝试了一些事情,发现当透明部分后面的桌面发生变化时,它实际上并没有被重新绘制。例如,如果我打开任务管理器并将其放在窗口后面,您不会看到它自行刷新。这与我所看到的透明度水平是有道理的。有没有一个函数可以让Windows重绘窗口后面的区域?

编辑3: 我尝试更改表单上的一些属性,但它们都会导致表单绘制不透明的黑色:

this.AllowTransparency = true;
this.DoubleBuffered = true;
this.Opacity = .99;

我将尝试为透明部分创建一个单独的窗口,如 overslacked 提到的,但仍然欢迎任何其他想法。

最佳答案

实际上,我想我会称之为预期行为。我要做的是将背景渲染到内存中的位图,然后在绘制事件中将其复制到表单(基本双缓冲)。

如果我离基地很远,你可以发布屏幕截图吗?我不知道我的想象是否正确。

编辑:

我想知道你对 OnPaintBackground 的使用...在 .NET 之前,如果你正在进行双缓冲,你会捕获并忽略 WM_ERASKBKGND 消息(以防止闪烁),将图像渲染到屏幕外缓冲区,并在 WM_PAINT 上从缓冲区复制到屏幕。因此,请尝试从 OnPaintBackground 更改为 OnPaint。

我在 .NET 中没有做过太多这样的事情,但我以前已经很好地处理过它了;只是不知道翻译得好不好!

编辑2:

马克,我越想你想做的事情,就越出现问题。我打算建议创建一个专门用于捕获屏幕并将其渲染变暗的后台线程;但是,为了删除您自己的表单,您必须将可见性设置为 false,这会产生其他问题......

如果你不愿意放弃,我建议创建两个窗口并将它们“绑定(bind)”在一起。为背景窗口创建一个半不透明窗口(通过设置不透明度),并为前景创建第二个“正常”窗口。在前景窗口上使用 SetWindowRgn 来切除背景并将它们放置在彼此的顶部。

祝你好运!

关于c# - C# .NET 3.5 WinForms 部分透明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/873470/

相关文章:

c# - MouseWheel 事件不以 120 为增量滚动

c# - 如何使用 Interop 加载 Excel 插件

c# - 如何使用WPF应用程序覆盖Prism中的默认区域管理器实现?

.net - 从 .NET 类型获取 XML 数据类型?

c# - C# .NET 位图的最大分辨率是多少?

.net - 封闭式和封闭式事件的区别

c# - 用C#处理HTML文档

c# - 故障排除 : Why doesn't type inference fail here?

c# - TextBox 在 '\0' 字符处截断字符串

c# - 自定义,复杂的动态反射解决方案-C#