【问题标题】:How do I change background colour of tab control in Winforms?如何更改 Winforms 中选项卡控件的背景颜色?
【发布时间】:2011-07-30 23:15:56
【问题描述】:

有没有办法改变winforms中tab控件的背景色,使其周围没有白色边框?

我尝试了几种不同的方法,但它们都导致显示相同的白色边框。

【问题讨论】:

  • 实现这一点的唯一方法是绘制 tabcontrol 本身。 Here's an example 在 CodeProject.com 上
  • 不,你会得到主题颜色。您可以关闭控件的视觉样式,但这会使其恢复为战舰灰色,但仍然无法更改。

标签: c# winforms


【解决方案1】:

TabControl 对自定义的支持很差。我已经成功使用了this custom tab control。如果您想像我一样更改外观,该代码非常有用。

【讨论】:

    【解决方案2】:

    我只能想到将 Appearance 属性更改为 Buttons

    MSDN TabControl Appearance

    【讨论】:

      【解决方案3】:

      首先你需要从 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(哈哈),而无需从头开始绘制。

      【讨论】:

      • 很好的解决方案,无需创建新控件并且还使用 BufferedGraphics
      • I noticed a problem while using this though.. when the tabs are wider than the tab control so those two arrows appear, everything falls apart.我建议避免这种情况。
      【解决方案4】:

      更简单(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);
        }
        

      【讨论】:

      • 我认为这不能解决 Tom 更改边缘和顶部选项卡本身(即标题)颜色的需要。 TabPage 的客户区本身会按照您的描述进行更改,也可以通过设计器中的 TabPage.BackColor 来完成。通过 Rhapsody 的 CodeProject 链接,还可以在此处查看 LauraM 对其限制的回复:stackoverflow.com/questions/67300/… 最后,还要考虑这个线程:stackoverflow.com/questions/5338587/set-tabpage-header-color
      • 这只会改变标签项的背景,而不是标题的背景!
      【解决方案5】:

      在选项卡控件的顶部(而不是内部)放置一个面板并在属性中设置颜色。 根据需要调用 Panelx.Hide() 和 Panelx.Show()。

      【讨论】:

        猜你喜欢
        • 2018-02-04
        • 1970-01-01
        • 2013-04-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-06
        • 1970-01-01
        • 2017-04-24
        • 1970-01-01
        相关资源
        最近更新 更多