C# Winform 中真正意义的透明控件

在稍微复杂的交互应用中,避免不了耗时的操作,这时候总希望给用户明确的提示,表示程序在运行中暂时不能进行其他操作。显示一个半透明的处于等待状态的遮罩层是很好的方法。在Web应用程序中直接设置Div的透明度然后覆盖操作界面就好,但是Winform的好像并没有提供透明度之类的属性。关于Background 中的 Transport 是特指背景透明的,其实质是继承父容器的背景颜色或者图片,在效果上看起来是一致的,但是如果父容器中包含其他的控件,则这种透明是无法显示这些控件的。此外还有一种真正意义的透明,它在隐藏在 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
       ...
    }

在枚举定义中可以看到 背景透明(SupportsTransparentBackColor) 和透明度(Opaque)的定义。操作系统在创建控件句柄时会传递这些设置过的特性,最终实现我们想要的效果。

使用.Net 的组建模型,只要在继承子类的初始化中设置这些属性即可。

SetStyle(ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);

对于透明只需要设置 ControlStyles.Opaque 即可,后面俩个选项有利于增强控件绘制更新的效率。当然这里的“透明“  是完全的透明,直接显示它下面的父容器内容,这样赤果果的感觉太过突兀了。

这里可以再引入 透明度(Alpha)的概念了,透明度的实现可以在绘制事件中通过 Argb 颜色模式去控制,参考代码如下:

/// <summary>
/// 自定义绘制窗体
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
	 定义颜色的透明度
	Color drawColor = Color.FromArgb(this._alpha, this.BackColor);
	 定义画笔
	Pen labelBorderPen = new Pen(drawColor, 0);
	SolidBrush  labelBackColorBrush = new SolidBrush(drawColor);
	 绘制背景色
	e.Graphics.DrawRectangle(labelBorderPen, 0, 0, Size.Width, Size.Height);
	e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, Size.Width, Size.Height);

	base.OnPaint(e);
}


除了套用组建模型,也可以使用更底层的句柄参数来达到同样的效果,这时候需要重载 CreateParams 属性,如下:

/// <summary>
/// 控件透明特性
/// </summary>
protected override CreateParams CreateParams
{
	get
	{
		CreateParams cp = base.CreateParams;
		// 开启 WS_EX_TRANSPARENT,使控件支持透明
		cp.ExStyle |= 0x20;  
		return cp;
	}
}

但是,我在尝试后发现 CreateParams 方式会发生边界阴影的问题,应该是同样缺少某些特性设定吧,大家找到的话可以Mark给我哈,谢谢

MSDN 关于扩展特性的说明 扩展的窗口样式  


下面贴俩张前后的效果图:

151951_HxyL_559187.jpg           151955_aWwk_559187.jpg

链接是一个实现的控件类,以供参考:LoadingPanel

调用也比较简单 :

 // 打开遮罩层
 loadingPanel1.ShowWaitingPanel();
 // 关闭遮罩层
 loadingPanel1.CloseWaitingPanel();

122407_3NWE_559187.png

@MISS BingBing  o(^▽^)o

Good Good study ,Day Day  Up

转载于:https://my.oschina.net/HenuToater/blog/520649

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值