Winform重寫CreateParams實現控件的透明顯示(Panel爲例)

前陣子做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);
            }
        }
    }



發佈了21 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章