![](/img/trans.png)
[英]How do I tell which tab you are moving from/to in a WinForms tab control?
[英]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
更简单(IMO):将绘制处理程序添加到 TabPage(不是顶级 TabControl,而是其中的 TabPage,然后以您想要的颜色绘制背景矩形。
在设计器中或“手动”中,将 Paint 事件处理程序添加到 TabPage:
Page1.Paint += tabpage_Paint; // custom paint event so we get the backcolor we want
在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.