C# 不透明问题

C# 不透明问题,c#,winforms,C#,Winforms,我试图画一个半透明的背景,然后在上面画一些不透明的元素 为什么我不能做这样的事 protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); this.Opacity = 0.5; pe.Graphics.FillRectangle(trans_black_brush, square_rect_big); this.Opacity = 1; pe.Graphics.FillR

我试图画一个半透明的背景,然后在上面画一些不透明的元素

为什么我不能做这样的事

protected override void OnPaint(PaintEventArgs pe)
{
    base.OnPaint(pe);

    this.Opacity = 0.5;
    pe.Graphics.FillRectangle(trans_black_brush, square_rect_big);
    this.Opacity = 1;
    pe.Graphics.FillRectangle(solid_red_brush, square_rect);
}
如果对表单绘图有更好理解的人能告诉我为什么这不起作用,我将不胜感激:)

更新: 该解决方案有3种形式: 1) 主(程序、按钮等) 2) 半透明背景(屏幕大小,使用不透明度) 3) 透明背景,但顶部有实心笔刷

在Form2的构造函数中,我有:

Foreground = new FormForeground(this);
private Form_FormBackground m_Parent;

public FormForeground(FormBackground parent)
{
InitializeComponent();
FormBackground m_Parent = parent;
...
}
在Form3的构造函数中,我有:

Foreground = new FormForeground(this);
private Form_FormBackground m_Parent;

public FormForeground(FormBackground parent)
{
InitializeComponent();
FormBackground m_Parent = parent;
...
}
无论何时单击鼠标并使用鼠标在表格3中绘制, 我更新父对象的矩形,如下所示:

private void _UpdateParent()
{
    m_Parent.s_DrawArea = m_DrawArea;
    m_Parent.Invalidate();
}
然后,父窗体2在绘制标记区域的位置执行OnPaint()

它确实可以工作,但是与直接在form3中绘制相比,绘图确实有点滞后(因为绘制区域需要在整个表单中透明,因此无法生成所需的结果).

这不起作用,因为它是
表单的一个属性
,将始终使整个表单及其所有内容具有当前值。不过,它非常适合将窗体淡入淡出

你不能用一种形式来实现你想要的

相反,您将需要两个同步化的表单

一个可以有点不透明,让桌面发光;另一个必须是透明的,通过使用
TransparencyKey
属性,您可以在其上绘制

要同步这两个表单代码,请执行
Move
ResizeEnd
事件

对于首次设置,请使用如下代码:

private void Form1_Move(object sender, EventArgs e)
{
    form0.Size = Size;
    form0.Location = Location;
}

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    form0.Size = Size;
    form0.Location = Location;
}
用于创建半透明外观的虚拟窗体:

Form form0 = new Form() { Opacity = 0.33f , BackColor = Color.Black};
在Form1的
Load
事件中:

TransparencyKey = Color.FromArgb(255, 147, 151, 162);
BackColor = TransparencyKey;
DoubleBuffered = true;

form0.Enabled = false;
form0.BringToFront();
form0.Show();
form0.Size = Size;
form0.Location = Location;
BringToFront();
Move
ResizeEnd
事件中,代码可能如下:

private void Form1_Move(object sender, EventArgs e)
{
    form0.Size = Size;
    form0.Location = Location;
}

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    form0.Size = Size;
    form0.Location = Location;
}
你可能还想研究一下,这也展示了一种夹心两种形式的方法

请注意,我选择了一种相当随机的颜色,而不是更常见的命名颜色紫红色或任何命名颜色。这是因为我

  • 不想在绘图中意外使用它,thius breaking使错误的点透明,而且
  • 不想让表单对鼠标操作透明,也就是“点击”。由于一些奇怪的遗留原因,在使用紫红色(可能还有其他颜色)时会发生这种情况

如果您需要透明,那么winforms确实不是您想要使用的,它的图形处理(gdi+)总是在某些方面遇到困难,因为它的整个透明处理是一种黑客行为,它的整个透明处理是一种温和的黑客行为。官方的说法是:通过复制控件的父级背景来伪造透明度;这意味着在其他限制中:不允许重叠,任何动态都相当困难。谢谢你,TaW。我已经建立了3个表格。第一个是主程序。第二个是背景(不透明度),第三个是绘制的前景。表格1和表格2非常有效,问题是表格3拒绝透明。我无法将BackColor设置为Color.Transparent。如果我将透明键和背景色设置为相同,我将无法移动鼠标并绘制(因为窗体不再存在,有点看不见)您选择了哪种背景色?也许是紫红色?这是唯一要避免的一个,因为它使表单“点击通过”…感谢您提出这个问题。。到目前为止,我已经尝试了不同的颜色(不是你提到的那种),现在我随机尝试了CadetBlue,效果很好!我以前试过的颜色是标准的,黑、白、红、粉、青灰色。。我想知道为什么颜色有不同的效果。我试图实现的一件事是通过两种形式使选择透明,因此我设置了相同的透明键,并且所选矩形填充了相同的颜色。绘制的长方体不会从前景中出血。我希望这样做,无论选择什么,都能通过这两种形式100%透明。有没有办法做到这一点?我怎样才能把表格3中的选择框矩形变成表格2,这样我就可以在那里画它了?嗯,我想我还不太明白。但是你总是可以做的,因为所有的形状都有相同的大小,就是从顶部拾取坐标,但在较低的形状上绘制。我希望你用一种正确的(即持续的)方式来画图。顺便说一句,通过模拟和最大化表格来检查!这些表格现在是如何堆放的?主-半透明-透明?您想让绘图放在哪个位置?