新建项目CustomTabControl
,对TabControl
控件的使用和主要功能进行介绍,并用于后续对其进行优化测试。
tabControl使用介绍
TabControl
是一个分页切换(tab)控件,不同的页框内可以呈现不同的内容。直接看一下默认拖拽出来的tabcontrol效果。
设置Dock
属性为Fill
。尝试调整后面的几种效果或功能。
调整tab标签大小
TabCtrol
标签的宽高默认是跟随文字自动变化的。并且默认无法调整宽度(正好适应文字)
调整ItemSize
宽高为80、36,高度会发生变换,但是宽度仍然是使用文字。需要设置SizeModel
为Fixed
使宽度值的设置生效。
有的时候调整tab宽度后会导致标签文本仍然是水平居中的。通过调整tabpage的padding可以调整tab内的边距大小,达到不水平居中的效果。
HotTrack
属性,设置鼠标经过选项卡时外观发生变化,但是没有任何效果(区别)。tabControl1.HotTrack = true;
设置选项卡在tabcontrol左侧(Alignment
)
默认选项卡显示在tabcontrol的顶部左侧,可以通过Alignment
属性调整其位置在左侧(很常见的一种效果)
但是,TabControl提供的选项卡位置调整后,无法很好的处理文本显示。
tabControl1.Alignment = TabAlignment.Left;
:
可以看到,问题是无法做到水平显示选项卡文字,解决办法是,需要在DrawItem
事件中处理标题绘制,具体见本篇后面的TabControl正确显示位于两边的tab选项卡(Left/Right)。
设置选项卡显示为Button效果
Appearance
外观设置显示的效果:
tabControl1.Appearance = TabAppearance.FlatButtons;
tabControl1.Appearance = TabAppearance.Buttons;
设置多行选项卡
如果tabpage有很多,选项卡也很多的情况下,还可以设置显示为多行选项卡。
tabControl1.Multiline = true;
for (int i = 0; i < 6; i++)
{
tabControl1.TabPages.Add("项目" + (2 + i));
}
结果如下:
从TabControl中移除或隐藏tabpage的方法
TabPage并未提供Visiable
等可见性的属性,可以通过移除其父控件或TabPages.Remove
实现类似效果。
tabControl1.TabPages.Remove(tabPage2);
或 tabPage2.Parent = null;
用来实现移除或隐藏tabPage2
。
隐藏TabControl头部的选项卡
如果想要实现隐藏TabControl
顶部的选项卡部分,可以通过如下过程实现:
SizeMode
设置为Fixed
。- 各个
TabPage
的Text
为空。 ItemSize
为Width=0;Height=1;
。Apperarance
设置为FlatButtons
(去除顶部线条)。
tabControl1.SizeMode = TabSizeMode.Fixed;
foreach (TabPage page in tabControl1.TabPages)
{
page.Text = "";
}
tabControl1.ItemSize = new Size(0, 1);
// 去除线条效果(上面的设置仍然会在tabControl的顶部出现线条)
tabControl1.Appearance = TabAppearance.FlatButtons;
SelectedTab或SelectedIndex用于切换tab选项卡
tabControl1.SelectedTab = tabPage2;
// 或
tabControl1.SelectedIndex = 1;
DeselectTab()
使指定索引的选项卡后面的选项卡成为当前选项卡
禁用TabPage
某些情况下可能需要限制对数据的访问,比如管理员有权访问某些 TabPage
页面信息,而其他用户不能访问。
主要实现过程:
- 在
SelectedIndexChanged
事件方法中进行处理(在tab切换到下一个时触发) - 在允许用户访问tab之前检查用户认证(用户名、用户权限认证等)
- 如果用户有正确的认证或权限,则显示点击的tab页;否则,显示一个消息框或其他界面,提示用户无权访问,并返回之前的tab。
最正确或推荐的做法(简洁编程的方法)是,在窗体(Form)的Load
事件中,执行权限认证,并根据不同权限,初始化显示或隐藏不同的选项卡(tab)。
tabControl1.TabPages.Remove(tabPage2);
或tabPage2.Parent = null;
。
如下是处理过程:
tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;
//.....
private void TabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedTab == tabPage2)
{
if (!CredentialCheck)//检查认证
{
MessageBox.Show("无法加载标签页,没有足够的权限!");
tabControl1.SelectedTab = tabPage1; // 默认tabpage或之前的tabPage
}
}
}
TabControl正确显示位于两边的tab选项卡(Left/Right)
TabControl
的Alignment
属性可以将选项卡显示在左或右两边(垂直),但是默认垂直显示非常糟糕,因为如果启用visual样式,TabPage的Text属性将不会显示在选项卡,并且在选项卡内无法修改文字方向。
优化办法是重绘TabControl(owner draw
特性),可以在DrawItem
事件中处理文字从左到右显示
- 添加
TabControl
控件。 - 设置
Alignment
为Left
。 - 设置
SizeMode
为Fixed
,所有tab有相同的宽度。 - 设置
ItemSize
合适的大小。ItemSize
的行为是作用在tab在top顶部时效果,因此,当为Left或Right时,想要使tab更宽,需要设置Height,更高则设置Width。(此处设置为Width、Height为40、100)。 - 设置DrawMode属性为
OwnerDrawFixed
。 - 添加
DrawItem
事件处理程序绘制文本。
tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
tabControl1.DrawItem += TabControl1_DrawItem;
//.....
Color tabSelectedBackColor = Color.IndianRed;
Color tabSelectedForeColor = Color.White;
private void TabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// 获取当前tabPage
TabPage _tabPage = tabControl1.TabPages[e.Index];
// 获取tab边界
Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
// 选中与未选中的(背景)颜色
if (e.State == DrawItemState.Selected)
{
_textBrush = new SolidBrush(tabSelectedForeColor);
g.FillRectangle(new SolidBrush(tabSelectedBackColor), e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
// tab上均有底部边框
e.DrawBackground();
}
// 使用控件字体,也可以使用自定义字体
Font _tabFont = e.Font;
// 绘制居中字符串
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
较为正确的显示左侧tab效果:
结合ImageList显示选项卡图标
添加ImageList
控件imageList1
,并向其中添加三张图片
设置TabControl
的ImageList
属性为添加的imageList1
;设置TabPage
的ImageIndex
为对应的imageList1
中的索引。
这样就可以在选项卡上显示图标了。
效果如下: