簡體   English   中英

如何更改 Winforms 中選項卡控件的背景顏色?

[英]How do I change background colour of tab control in Winforms?

有沒有辦法在winforms中更改選項卡控件的背景顏色,使其周圍沒有白色邊框?

我嘗試了幾種不同的方法,但它們都導致顯示相同的白色邊框。

TabControl對自定義的支持很差。 我已經成功地使用了這個自定義選項卡控件 如果您想像我一樣更改外觀,該代碼非常有用。

首先,您需要從 TabControl 創建一個派生類。 到目前為止一切順利,但現在它變臟了。

因為 TabControl 不會調用OnPaint ,所以我們必須重寫WndProc來處理 WM_PAINT 消息。 在那里,我們繼續用我們喜歡的顏色繪制背景。

 protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if(m.Msg == (int) WindowsMessages.Win32Messages.WM_PAINT)
        {
            using (Graphics g = this.CreateGraphics())
            {
                //Double buffering stuff...
                BufferedGraphicsContext currentContext;
                BufferedGraphics myBuffer;
                currentContext = BufferedGraphicsManager.Current;
                myBuffer = currentContext.Allocate(g,
                   this.ClientRectangle);

                Rectangle r = ClientRectangle;

                //Painting background
                if(Enabled)
                    myBuffer.Graphics.FillRectangle(new SolidBrush(_backColor), r);
                else
                    myBuffer.Graphics.FillRectangle(Brushes.LightGray, r);

                //Painting border
                r.Height = this.DisplayRectangle.Height +1; //Using display rectangle hight because it excludes the tab headers already
                r.Y = this.DisplayRectangle.Y - 1; //Same for Y coordinate
                r.Width -= 5;
                r.X += 1;

                if(Enabled)
                    myBuffer.Graphics.DrawRectangle(new Pen(Color.FromArgb(255, 133, 158, 191), 1), r);
                else
                    myBuffer.Graphics.DrawRectangle(Pens.DarkGray, r);

                myBuffer.Render();
                myBuffer.Dispose();

                //Actual painting of items after Background was painted
                foreach (int index in ItemArgs.Keys)
                {
                    CustomDrawItem(ItemArgs[index]);
                }

            }
        }    
    }

我在這個方法中做進一步的繪制,所以對於這個問題看起來有點矯枉過正,但只是忽略了不必要的東西。 還要注意foreach循環。 我稍后會談到這個。

問題是TabControl在其自己的 WM_PAINT之前繪制其項目(選項卡標題),因此我們的背景將被繪制在頂部,這使得它們不可見。 為了解決這個問題,我為DrawItem創建了一個EventHandler ,如下所示:

    private void DrawItemHandler(object sender, DrawItemEventArgs e)
    {
        //Save information about item in dictionary but dont do actual drawing
        if (!ItemArgs.ContainsKey(e.Index))
            ItemArgs.Add(e.Index, e);
        else
            ItemArgs[e.Index] = e;
    }

我將DrawItemEventArgs保存到字典中(在我的情況下稱為“ItemArgs”),以便以后可以訪問它們。 這就是幾秒鍾前的foreach發揮作用的地方。 它調用一個方法,我在其中繪制選項卡標題,該方法將我們之前保存的DrawItemEventArgs作為參數以正確的狀態和位置繪制項目。

因此,簡而言之,我們正在攔截選項卡標題的繪制以延遲它,直到我們完成繪制背景。

這個解決方案不是最佳的,但它可以工作,並且它是唯一可以做的事情來獲得對TabControl的更多控制(lol),而無需從頭開始繪制它。

我只能想到將 Appearance 屬性更改為 Buttons

MSDN TabControl 外觀

更簡單(IMO):將繪制處理程序添加到 TabPage(不是頂級 TabControl,而是其中的 TabPage,然后以您想要的顏色繪制背景矩形。

  1. 在設計器中或“手動”中,將 Paint 事件處理程序添加到 TabPage:

     Page1.Paint += tabpage_Paint; // custom paint event so we get the backcolor we want
  2. 在paint方法中,將頁面矩形繪制成你想要的顏色(在我的例子中,我希望它遵循標准的BackColor):

     // force the tab background to the current BackColor private void tabpage_Paint(object sender, PaintEventArgs e) { SolidBrush fillBrush = new SolidBrush(BackColor); e.Graphics.FillRectangle(fillBrush, e.ClipRectangle); }

將面板放在選項卡控件的頂部(而不是內部)並在屬性中設置顏色。 根據需要調用 Panelx.Hide() 和 Panelx.Show()。

不幸的是,在繪制控件時會處理背景顏色屬性。 我的建議是做我所做的並創建一個用戶控件來模仿標簽控制器。

我使用菜單條作為選項卡,並將第二個用戶控件停靠為父用戶控件的填充。 在第二個用戶控件中,我能夠為所述選項卡添加我需要的任何內容。

更難的部分是您必須構建所有功能以使其用作選項卡控件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM