我如何使我的表格透明,但我画的不是?

时间:2009-10-09 04:42:08

标签: c# wpf winforms transparency

我尝试将表单的不透明度设置为50%,然后在其上绘制一个字符串。似乎我在其上绘制的字符串也具有50%的不透明度。我如何绘制非透明字符串,但让表单背景显示50%?

如果可能的话,也愿意在WPF中这样做,但我需要明确的指示或示例项目,因为我以前从未这样做过。

为了澄清,我希望表单背景是黑色的80%不透明,然后我想在它上面绘制文字等,让它看起来100%不透明。

7 个答案:

答案 0 :(得分:19)

这在WPF中很容易完成:

  1. 在窗口上设置WindowStyle =“无”(注意:这是必需的,你不能有透明度和标准的窗口镀铬)
  2. 在窗口上设置AllowTransparency =“True”
  3. 使用具有透明度的画笔在窗口上设置背景,例如Background =“#AAFFFFFF”
  4. 以下是一个快速示例:

    <Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300" AllowsTransparency="True" Background="#AAFFFFFF" WindowStyle="None">
    <Grid>
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="Bold">Hello World!</TextBlock>
    </Grid>
    

    现在显然,由于您已禁用标准Windows镶边,因此您需要提供自己的按钮来关闭/最小化/最大化/拖动窗口。你可以自己很容易地做到这一点,或者你可以考虑购买Blendables这样的东西,它带有你可以使用的“Chromeless Window”控件。

答案 1 :(得分:4)

答案 2 :(得分:1)

我想到的一个解决方法是使用两个叠加在一起的窗口。以50%不透明度渲染“底部”窗口,然后所有者将文本绘制到覆盖在另一个上面的窗口。如果您正在进行标签式显示,这可能很简单,但如果您需要大量用户输入,可能会很快变得复杂,这可能需要过滤到“主”或“底部”窗口。

所以,我得到了它的工作,但它有点松鼠。两个窗口解决方案看起来很有希望,直到我发现.Net或Win32甚至隐含地引用它时会做一些奇怪的自动育儿事情。可能与消息的抽取方式有关。主要父级持有应用程序消息泵,而int guess隐含地是父级...

我尝试了一堆变通方法,但下面的这个计时器工作效果最好。在任何情况下,它可能是一个更好的做法的线索......


// the "main" or transparent window. Notice it just sets and runs the timer
using System;
using System.Windows.Forms;
namespace TransparencyPlusNottransparentTest
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Program.ShowNontransparency();
    }
}

}

// the "top" or not transparent window. Notice it does owner draw on // transparent background. The design-time settings are also sans border etc. using System.Drawing; using System.Windows.Forms;

namespace TransparencyPlusNottransparentTest { public partial class FormTop : Form { public FormTop() { InitializeComponent(); BackColor = Color.Firebrick; TransparencyKey = Color.Firebrick; }

    private void FormTop_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawString("Hello Whirrled!", new Font("Tahoma", 14f), Brushes.Black, 10f, 10f );
    }
}

}

// The control of this whole spiel. It instantiates both windows, // sets the main as the main app window and hosts the public // hacky method to force the non-transparent window to show up on top // and offset so it doesn't obscure the top of the main window. using System; using System.Drawing; using System.Windows.Forms;

namespace TransparencyPlusNottransparentTest { static class Program { private static FormMain _formMain; private static FormTop _formTop; private const int XY_OFFSET = 30;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        _formTop = new FormTop();
        _formTop.Show(null);

        _formMain = new FormMain();

        Application.Run(_formMain);
    }

    public static void ShowNontransparency()
    {
        _formTop.Location = 
            new Point(
            _formMain.Location.X + XY_OFFSET, 
            _formMain.Location.Y + XY_OFFSET);

        _formTop.BringToFront();
    }
}

}

答案 3 :(得分:0)

ControlStyles枚举MSDN中的

有一个名为SupportsTransparentBackColor的值。在你的表单构造函数中运行:

SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);

然后您可以将背景颜色设置为Color.Transparent。

希望这有帮助。

答案 4 :(得分:0)

使用TransparencyKey将窗口渲染为透明。使用您的背景颜色创建一个空面板,并为其指定所需的不透明度。

然后在一个单独的容器/面板(本身是上面创建的半透明面板的兄弟姐妹)中创建所有孩子,并让它根本不渲染背景。

这应该会给你半透明背景但可见控件的效果。

答案 5 :(得分:0)

在winforms中,MSDN说:

  

Opacity属性使您可以   指定透明度   形式及其控制。当这个   property设置为小于的值   100%(1.00),整个表格,   包括边界,更多   透明的。

因此,您设置不透明度的表单的任何子控件都将更改其不透明度。如果要在单个控件上实现不同级别的不透明度,则必须切换到WPF。

答案 6 :(得分:0)

我认为这是一个WinForms项目,虽然你说你愿意尝试WPF。

Lemme切换到我的横向思维上限:任何特殊原因你都不能假装它?如在,在PhotoShop Elements或Paint Shop Pro中制作位图,或者将某些位置设置为WinForm的整个背景,并且只需绘制部分透明区域,控件将放置在该区域上就在那个位图上?