关闭

C# 系统应用之透明罩MyOpaqueLayer实现360界面阴影效果

标签: C#系统应用透明罩MyOpaqueLayer界面设计自定义控件
4185人阅读 评论(0) 收藏 举报
分类:

在完成“个人电脑使用记录清除软件”中,我设计的winform界面需要应用到类似于"360安全卫士"的透明罩效果,文章主要引述了如何使用自定义组件MyOpaqueLayer,并自定义类OpaqueCommand中定义显示透明罩函数ShowOpaqueLayer和隐藏透明罩函数HideOpaqueLayer实现,同时如何对控件添加透明罩及遇到的问题.

一.自定义透明罩MyOpaqueLayer组件

(声明:此段代码引用自海华博客http://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html)
在添加透明罩控件\组件时,我的想法是"右键项目->添加->添加控件",但添加没有成功,在网上也没有讲到该添加的基础方法,由于以前也没遇到过自定义控件的问题,所以只好采取的方法是拖拽修改过MyOpaqueLayer.cs文件至项目中,具体代码如下(含详细注释):

using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace MyOpaqueLayer
{
    /* 
     * [ToolboxBitmap(typeof(MyOpaqueLayer))]
     * 用于指定当把你做好的自定义控件添加到工具栏时,工具栏显示的图标。
     * 正确写法应该是
     * [ToolboxBitmap(typeof(XXXXControl),"xxx.bmp")]
     * 其中XXXXControl是你的自定义控件,"xxx.bmp"是你要用的图标名称。
    */
    [ToolboxBitmap(typeof(MyOpaqueLayer))]

    /// <summary>
    /// 自定义控件:透明罩控件(继承Control)
    /// </summary>
    public class MyOpaqueLayer : System.Windows.Forms.Control
    {
        private bool _transparentBG = true;       //是否使用透明
        private int _alpha = 125;                 //设置透明度
        
        private System.ComponentModel.Container components = new System.ComponentModel.Container();
        public MyOpaqueLayer()
            : this(125, true)
        {
        }

        public MyOpaqueLayer(int Alpha, bool IsShowLoadingImage)
        {
            SetStyle(System.Windows.Forms.ControlStyles.Opaque, true);  //设置控件样式
            base.CreateControl();                                       //创建控件
            this._alpha = Alpha;
            //放置加载进度的图片代码此处被省略
        }

        //释放组件占用内存
        protected override void Dispose(bool disposing)                 
        {
            if (disposing)
            {
                if (!((components == null)))
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

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

            Pen labelBorderPen;                     //定义Pen
            SolidBrush labelBackColorBrush;         //定义单色画笔

            if (_transparentBG)                     //使用透明
            {
                Color drawColor = Color.FromArgb(this._alpha, this.BackColor);
                labelBorderPen = new Pen(drawColor, 0);
                labelBackColorBrush = new SolidBrush(drawColor);
            }
            else
            {
                labelBorderPen = new Pen(this.BackColor, 0);
                labelBackColorBrush = new SolidBrush(this.BackColor);
            }
            base.OnPaint(e);
            vlblControlWidth = this.Size.Width;
            vlblControlHeight = this.Size.Height;
            e.Graphics.DrawRectangle(labelBorderPen, 0, 0, vlblControlWidth, vlblControlHeight);
            e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, vlblControlWidth, vlblControlHeight);
        }

        //获取创建控件句柄时所需要的创建参数
        protected override CreateParams CreateParams //v1.10 
        {
            get
            {
                CreateParams cp = base.CreateParams;  //扩展派生类CreateParams属性
                cp.ExStyle |= 0x00000020;             //开启WS_EX_TRANSPARENT,使控件支持透明
                return cp;
            }
        }

        /*
         * [Category("myOpaqueLayer"), Description("是否使用透明,默认为True")]
         * 一般用于说明你自定义控件的属性(Property)
         * Category用于说明该属性属于哪个分类,Description自然就是该属性的含义解释。
         */
        [Category("MyOpaqueLayer"), Description("是否使用透明,默认为True")]
        public bool TransparentBG
        {
            get
            {
                return _transparentBG;
            }
            set
            {
                _transparentBG = value;
                this.Invalidate();
            }
        }
        //设置透明度
        [Category("MyOpaqueLayer"), Description("设置透明度")]
        public int Alpha
        {
            get
            {
                return _alpha;
            }
            set
            {
                _alpha = value;
                this.Invalidate();
            }
        }

        //初始化窗体
        private void InitializeComponent()
        {
            this.SuspendLayout();      //临时挂起控件的布局逻辑,它与ResumeLayout()配合使用
            this.ResumeLayout(false);  //恢复正常逻辑
        }
    }
}

二.自定义透明罩类OpaqueCommand

在第一部分我们已经自定义透明罩组件,此时需要自定义类OpaqueCommand并调用其方法ShowOpaqueLayer(显示遮罩层)和HideOpaqueLayer(隐藏遮罩层).可以在“解决方法”中右键项目名->添加->类,具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EMSecure
{
    class OpaqueCommand
    {
        //透明罩
        private MyOpaqueLayer.MyOpaqueLayer m_OpaqueLayer = null;

        /// <summary>
        /// 显示透明层
        /// </summary>
        /// <param name="control">控件</param>
        /// <param name="alpha">透明度</param>
        /// <param name="isShowLoadingImage">是否显示图标</param>
        public void ShowOpaqueLayer(Control control, int alpha, bool isShowLoadingImage)
        {
            try
            {
                if (this.m_OpaqueLayer == null)
                {
                    this.m_OpaqueLayer = new MyOpaqueLayer.MyOpaqueLayer(alpha, isShowLoadingImage);
                    control.Controls.Add(this.m_OpaqueLayer);
                    this.m_OpaqueLayer.Dock = DockStyle.Fill;
                    this.m_OpaqueLayer.BringToFront();
                }
                this.m_OpaqueLayer.Enabled = true;
                this.m_OpaqueLayer.Visible = true;
            }
            catch (Exception msg)              //异常处理
            {
                MessageBox.Show(msg.Message);
            }
        }

        /// <summary>
        /// 隐藏透明层
        /// </summary>
        public void HideOpaqueLayer()
        {
            try
            {
                if (this.m_OpaqueLayer != null)
                {
                    this.m_OpaqueLayer.Visible = false;
                    this.m_OpaqueLayer.Enabled = false;
                }
            }
            catch (Exception msg)             //异常处理
            {
                MessageBox.Show(msg.Message);
            }
        }
    }
}

三.使用透明罩

在定义透明罩控件和类后,如何实现该界面的效果,我推荐的方法是:
1.设置toolBar控件,在items(集合)中添加相应的图标\文字构成不同的ToolItem,每次透明罩遮掩不同的Item即可,如果是wfp使用TabControl\TabItem.但由于toolBar被toolStrip替代,不太会使用该控件,但仍然推荐该方法(有的没有定义透明罩控件,而是通过3张透明程度不同的图,设置可见属性实现该效果).运行结果:


2.在代码设计器Form中添加MyOpaqueLayer控件,此时就能看见6个透明罩的MyOpaqueLayer控件,该方法不需要设置自定义类OpaqueCommand调用其方法,而是设置如下代码:

//鼠标离开
private void myOpaqueLayer1_MouseLeave(object sender, EventArgs e)
{
    this.myOpaqueLayer1.Visible = false;
    this.label4.ForeColor = Color.White;
}
//鼠标进入
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
    this.myOpaqueLayer1.Visible = true;
    this.label4.ForeColor = Color.Yellow;
}

设计器中form如下图所示:

但由于不知道如何添加该控件拖动至设计器中,所以我采取的方法是
3.自定义6个panel,通过鼠标事件进入panelmol1_MouseEnter(object sender, EventArgs e)\鼠标离开事件panelmol1_MouseLeave(object sender, EventArgs e)\鼠标点击事件panelmol1_MouseClick(object sender, EventArgs e)实现,最后我的运行结果如下图所示:


下面只给出使用透明罩控件和类的基本调用代码并省略Click部分(因为做的不是很好),请读者体会与自己设计:

//自定义类OpaqueCommand
OpaqueCommand cmd = new OpaqueCommand();
//定义点击panel时透明罩情况
bool isClick = false;

//鼠标进入"清除IE"
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
    //透明罩设置 没点击才取消透明罩
    cmd.ShowOpaqueLayer(panel_mol1, 125, true);
}
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
    cmd.HideOpaqueLayer();
}

四.总结
个人感觉该设计还有很多地方需要自己改进,同时想实现ToolBar方法和了解如何添加自定义组件而不是拖拽,期望自己能解决这些问题.希望该文章对大家有所帮助,同时感谢下面3篇文章及博主,是讲述透明罩和如何自定义控件的文章,个人感觉非常不错.如果文章中有不足或错误的地方,请海涵!
(By:Eastmount 2014-3-10 中午2点 原创:
http://blog.csdn.net/eastmount)
参考资料及在线笔记:

1.C#实现Winform自定义半透明遮罩层-海华(主要参考透明罩的设定)
http://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html
2.C#中自定义控件-杨友山(自定义控件简述)
http://blog.csdn.net/yysyangyangyangshan/article/details/7078471
3.C#自定义控件开发-百度文库(详细介绍自定义控件\复合控件\扩展控件)
http://wenku.baidu.com/view/89a47f6e58fafab069dc02bf.html

2
0
查看评论

【转】C#实现Winform自定义半透明遮罩层

转自:http://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html 在网页中通过div+css实现半透明效果不难,今天我们看看一种在winfrom中实现的方法: 效果图如下,正常时: 显示遮罩层时: ...
  • zjwen2007
  • zjwen2007
  • 2014-11-26 10:00
  • 641

在C#中调用系统API使窗体下拥有阴影效果

  2007-12-16 00:09文章来源:http://blog.donews.com/dongshijun//昨天晚上看MSDN看见的一段通过使用SetClassLong函数使窗口下面拥有一个阴影效果,研究代码找资料弄了半个小时把它运用在了C#2.0上,特此一贴。由于我使用...
  • sweetsoft
  • sweetsoft
  • 2008-09-11 22:13
  • 1684

winform 自定义带阴影的panel控件

  • 2016-01-13 11:19
  • 100KB
  • 下载

C# WinForm窗体四周阴影效果

一、起因关于winform窗体无边框的问题很简单,只需要设置winform的窗体属性即可:FormBorderStyle = FormBorderStyle.None;但是这中无边框窗口实现的效果和背景完全没有层次的感觉,所以能加上阴影,突出窗口显示的感觉。二、网上搜索的解决方案方法 1首先,发现了...
  • myinc
  • myinc
  • 2017-09-08 21:04
  • 2699

C# WinForm无边框窗体设置阴影效果

1、添加引用 using System.Runtime.InteropServices; 2、定义常量值及函数 private const int CS_DropSHADOW = 0x20000; private const int GCL_STYLE = (-...
  • C_S_D_N_USER
  • C_S_D_N_USER
  • 2015-04-18 11:48
  • 4776

Winform Chart控件绘制阴影区域

先来看看效果 公司电力项目需要绘制这种工业图表,之前同事用Series绘制的 有点麻烦 需要计算起始点位置,后来我发现Chart控件本来就提供了这种阴影属性,简单方便 直接上代码 private void InitChart() { Chart...
  • xiaoyiyz
  • xiaoyiyz
  • 2015-08-27 10:14
  • 2323

C#自定义控件之-winform美化

对于系统自带的窗体,博主实在不敢恭维,测试时使用方便快捷,但真正项目中无法使用,只因不美观的外表,每次都很头疼窗体的美化,这里列出一些需要解决的问题和自己收集到的解决方法,如有错误请指出。 废话不多说先上一张最近写的一个小工具的效果图。 以上是工具的基本截图,在工具的制作中对窗体的自定义包括以下几点...
  • lcj401175209
  • lcj401175209
  • 2016-10-28 09:07
  • 5628

C#WinForm窗体四周阴影效果

  • 2017-09-08 15:31
  • 73KB
  • 下载

C# 实现panel 控件的阴影效果

  • 2009-06-30 17:07
  • 100KB
  • 下载

C# Winform仿360窗口菜单界面程序

  • 2013-04-21 13:49
  • 5.31MB
  • 下载
    个人资料
    • 访问:2326261次
    • 积分:21610
    • 等级:
    • 排名:第413名
    • 原创:270篇
    • 转载:10篇
    • 译文:0篇
    • 评论:1651条
    个人博客
    作者:杨秀璋
    学历:本科-北京理工大学
               硕士-北京理工大学
    现任教于贵财财经大学信息学院
    http://www.eastmountyxz.com

    简介:自幼受贵州大山的熏陶,养成了诚实质朴的性格。经过寒窗苦读,考入BIT,为完成自己的教师梦,放弃IT、航天等工作,成为贵财一名大学教师,并想把自己所学所感真心传授给自己的学生,帮助更多陌生人。

    贵州纵美路迢迢,
    为负劳心此一遭。
    收得破书三四本,
    也堪将去教尔曹。

    娜美人生,醉美生活。
    他和她经历风雨,慢慢变老。
    博客专栏
    牛人博客
    最新评论