Winform重写CreateParams实现控件的透明显示(Panel为例)

来源:互联网 发布:手机下载监控软件 编辑:程序博客网 时间:2024/05/05 19:49

前阵子做GIS,要实现图层的显示效果,尝试将2个PictureBox(该PictureBox实际是自定义的组件继承自panel,原本想直接重写PictureBox,但是前景和背景支持透明,叠在还是会有问题)叠在一起,将上面的一张图片的BackColor和ForeColor设为Color.Transparent,并不加载任何图片,希望能看见下面一张图片的内容,但始终无法实现,然后得知道Winform默认情况下是不支持透明通道的,所以查阅了相关知识后,尝试继承并重写Winform中控件的一些属性和方法,实现自定义的PictureBox并支持透明通道

现在我们尝试重写PictureBox

我们自定义一个抽象类(不抽象也可以),由于该类无须被实例化所以定义为抽象即可,让该类继承Panel

然后我们重写一下CreateParams属性,建议大家去谷歌一下与该属性相关的内容

重写内容如下

protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00000020;       // 实现透明样式
                return cp;
            }
        }

然后再考虑重写以下OnPaint事件,设置以下绘制时的相关属性,例如在构造函数中默认前景色和背景色都为透明

由于Onpaint中重写了一些属性,子类继承该类后无法实现刚刚重写的属性,需要自己在Override一遍,所以再Onpaint中再调用一个OnDraw()抽象方法,让子类去重写该抽象方法就可以了

最后我们再新建一个类去继承该类,作为具体的可实例化组件

public abstract class PanelExtend : Panel    {        protected Graphics graphics;        protected override CreateParams CreateParams        {            get            {                CreateParams cp = base.CreateParams;                cp.ExStyle |= 0x00000020; // 实现透明样式                return cp;            }        }        public PanelExtend()        {            this.BackColor = Color.Transparent;            this.ForeColor = Color.Transparent;        }        protected override void OnPaintBackground(PaintEventArgs pevent)        {        }        protected override void OnPaint(PaintEventArgs e)        {            this.graphics = e.Graphics;            this.graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;            this.graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;            this.graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;            this.graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;            this.graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;            OnDraw();        }        protected abstract void OnDraw();    }


再定义一个类,该类可实例化为具体工具栏组件,继承刚刚重写过Panel的抽象类PictureBoxExtend,并重写抽象类中的OnDraw()方法,该方法描述具体如何绘制

首先获取该组件的长宽,并确定绘制范围为整个组件的大小

然后再是一些具体的绘制要求,此处理应是3个If而不是if else,应该是先判断背景色,有背景色绘制背景色,然后有背景绘制背景,有前景色再绘制前景色,但是一般有背景就不用绘制背景色了,所以避免每次绘制3遍

public class PictureBoxModel : PanelExtend    {        public PictureBoxModel()        {                    }        protected override void OnDraw()        {            int width = this.Width;            int height = this.Height;            Rectangle recModel = new Rectangle(0, 0, width, height);            if (this.BackgroundImage != null)            {                this.graphics.DrawImage(this.BackgroundImage, recModel);            }            else if (this.ForeColor != Color.Transparent)            {                this.graphics.Clear(this.ForeColor);            }            else if (this.BackColor != Color.Transparent)            {                this.graphics.Clear(this.BackColor);            }        }    }



0 0