Winform透明控件

最新做一个项目,使用的是Winform,碰到一个问题,需要在后台执行某项任务的时候,画面显示“处理中”这样的半透明遮罩,Web项目中可以使用DIV(Css半透明),或者Wpf项目的话本身控件支持真透明(直接与DirectX进行交互),而Winform本身控件并不支持真正的透明,经过各种调查还是没有解决这个问题。

在网上查到的结果主要有两种。

1.指定ControlStyles。

// 摘要: 
    //     指定控件的样式和行为。
    [Flags]
    public enum ControlStyles     {
       ...
        // 摘要: 
        //     如果为 true,则控件被绘制为不透明的,不绘制背景。
        Opaque = 4,
         //
        // 摘要: 
        //     如果为 true,控件接受 alpha 组件小于 255 的 System.Windows.Forms.Control.BackColor 以模拟透明。仅在
        //     System.Windows.Forms.ControlStyles.UserPaint 位设置为 true 并且父控件派生自 System.Windows.Forms.Control
        //     时才模拟透明。
        SupportsTransparentBackColor = 2048
       ...
    }

在控件的构造函数中,指定样式。

public MyControl
{
   SetStyle(ControlStyles.Opaque | 
            ControlStyles.AllPaintingInWmPaint | 
            ControlStyles.UserPaint, true);
}

其中Opaque代表强制不画背景,

剩下的AllPaintingInWmPaint和UserPaint只是为了增强描画的效率。

当然如果为了实现自己的效果,还需要重写描画函数。

/// <summary>
        /// 自定义绘制窗体
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            float vlblControlWidth;
            float vlblControlHeight;

            Pen labelBorderPen;
            SolidBrush labelBackColorBrush;

            Color drawColor = Color.FromArgb(this._alpha, Color.Black);
            labelBorderPen = new Pen(drawColor, 0);
            labelBackColorBrush = new SolidBrush(drawColor);

            vlblControlWidth = this.Size.Width;
            vlblControlHeight = this.Size.Height;
            e.Graphics.DrawRectangle(labelBorderPen, 0, 0, vlblControlWidth, vlblControlHeight);
            e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, vlblControlWidth, vlblControlHeight);

            base.OnPaint(e);
        }

到此为止,程序运行的效果如下:

为了显示出控件的透明效果,透明度被固定的设置为了125,背景色为黑色,在这招下面放了2个按钮,OK,看起来很完美。但是。。。因为强制不描绘,如果使用Alt + Tab进行画面切换的话。。。,就变成了以下这个样子。。。

嗯?你问我这个是什么?没错,这个就是刚才的那个半透明遮罩,我只不过用Alt + tab切换到了Visual Studio, 然后又切换回来而已。在切换到Alt + tab之后,切换到Visual Studio的时候画面背景进行了重画(指的VisualStudio的窗口),这个之后,再次切换回Form1,由于强制控件不描画背景,就变成了上面的这个样子。不要告诉我“那你不要切换画面就好了”,反正我做不到。

还有上面写道的ControlStyles里面有一个SupportsTransparentBackColor,在控件构造函数中指定,并且将控件的BackGroundColor设置成Transparent,控件只是得到了支持父容器的透明,简单说,如果父容器中没有其他控件的话,可以得到透明效果,但是,如果父容器中含有其他的控件,就会失去透明效果,也可以说这是一种“假透明”。

2.重写CreateParams 

protected override CreateParams CreateParams
{
    get
    {
	CreateParams cp = base.CreateParams;
	// 开启 WS_EX_TRANSPARENT,使控件透明
	cp.ExStyle |= 0x20;  
	return cp;
    }
}

这个其实和1方法是大同小异, 个人觉得还不如第一个,也许是因为考虑不够周全,使用这种办法实现透明的时候,不仅在1中提到的问题没有得到解决,并且在拖动时还会有边界阴影的问题。

综上所述,我没有找到根本的解决控件透明的解决办法,社区里面的各位高手,如果您已经解决了上述的问题,或者您

 

转载于:https://my.oschina.net/u/2966716/blog/760603

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值