c#重写TabControl控件实现关闭按钮的方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c#重写TabControl控件实现关闭按钮的⽅法
1.c#⾥⾯的TabControl控件没有关闭按钮,⽽且很难看。
2.有⼀些已经做好的第三⽅控件,但是收费。
3.由于我的故障树推理诊断项⽬在绘图的时候允许同时打开多个⽂档进⾏操作,就要实现类似于浏览器的多标签功能,⽽且要可以关闭。
4.所以⾃⼰写⼀个类继承TabControl类,然后重写⼀些⾥⾯的⽅法即可实现。
5.特⾊:有关闭按钮,标签有背景颜⾊,选中的标签和没选中的颜⾊不⼀样,实现⿏标中键和右键的功能
先看我的项⽬中的完整代码,有很多代码是我的项⽬需要,可根据你的项⽬需求删减,核⼼的代码后⾯详细解释:
复制代码代码如下: /// <summary> /// 重写的TabControl控件带关闭按钮 /// </summary> public class MyTabControl : TabControl { private int iconWidth = 16; private int iconHeight = 16; private Image icon = null; private Brush biaocolor = Brushes.Silver; //选项卡的背景⾊ private Form_paint father;//⽗窗⼝,即绘图界⾯,为的是当选项卡全关后调⽤⽗窗⼝的dispose事件关闭⽗窗⼝ private AxMicrosoft.Office.Interop.VisOcx.AxDrawingControl axDrawingControl1; public MyTabControl(AxMicrosoft.Office.Interop.VisOcx.AxDrawingControl axDrawingControl) : base() { this.axDrawingControl1 = axDrawingControl; this.ItemSize = new Size(50, 25); //设置选项卡标签的⼤⼩,可改变⾼ 不可改变宽 //this.Appearance = TabAppearance.Buttons; //选项卡的显⽰模式 this.DrawMode = TabDrawMode.OwnerDrawFixed; icon = Properties.Resources.close.ToBitmap(); iconWidth = icon.Width; iconHeight = icon.Height; } /// <summary> /// 设置⽗窗⼝ /// </summary> /// <param name="fp">画图窗⼝</param> public void setFather(Form_paint fp) { this.father = fp; } /// <summary> /// 重写的绘制事
件 /// </summary> /// <param name="e"></param> protected override void OnDrawItem(DrawItemEventArgs e)//重写绘制事件。
{ Graphics g = e.Graphics; Rectangle r = GetTabRect(e.Index); if (e.Index ==
this.SelectedIndex) //当前选中的Tab页,设置不同的样式以⽰选中 { Brush selected_color = Brushes.Gold; //选中的项的背景⾊ g.FillRectangle(selected_color, r); //改变选项卡标签的背景⾊ string title =
this.TabPages[e.Index].Text + " "; g.DrawString(title, this.Font, new SolidBrush(Color.Black), new PointF(r.X + 3, r.Y + 6));//PointF选项卡标题的位置 r.Offset(r.Width - iconWidth - 3, 2); g.DrawImage(icon, new Point(r.X - 2, r.Y + 2));//选项卡上的图标的位置 fntTab = new System.Drawing.Font(e.Font, FontStyle.Bold); } else//⾮选中
的 { g.FillRectangle(biaocolor, r); //改变选项卡标签的背景⾊ string title = this.TabPages[e.Index].Text + " "; g.DrawString(title, this.Font, new SolidBrush(Color.Black), new PointF(r.X + 3, r.Y + 6));//PointF选项卡标题的位置 r.Offset(r.Width - iconWidth - 3, 2); g.DrawImage(icon, new Point(r.X - 2, r.Y + 2));//选项卡上的图标的位置 } } protected override void OnMouseClick(MouseEventArgs e) { #region 左键判断是否在关闭区域 if (e.Button == MouseButtons.Left) { Point p = e.Location; Rectangle r =
GetTabRect(this.SelectedIndex); r.Offset(r.Width - iconWidth - 3, 2); r.Width = iconWidth; r.Height = iconHeight; if (r.Contains(p)) //点击特定区域时才发⽣ { string temp =
this.SelectedTab.Text; if (temp[temp.Length - 5] == '*')//有变化才保存 { //确认是否保存VSD ⽂档到ft_doc_Path DialogResult response = MessageBox.Show("是否保存故障树" + + "到图形⽂件", "请确认", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (response == System.Windows.Forms.DialogResult.Yes)//确认保
存 { axDrawingControl1.Document.SaveAs(GlobalVariables.ft_doc_Path + axDrawingControl1.Document.Title + ".vsd");//保存当前⽂档到⽂件夹 string datetime =
DateTime.Now.ToString();//获取当前时间 helpTool.saveVsdDB(axDrawingControl1.Document.Title, datetime);//保存vsd⽂档到数据库 helpTool.setDatetimeToXml(axDrawingControl1.Document.Title, datetime);//如果信息已存在则将xml中的⽇期更新,如果不存在直接插⼊ this.SelectedTab.Text =
temp.Substring(0, temp.Length - 5) + " ";//保存后取消星号标志,还原为没变化的时候的样式 } else if (response == System.Windows.Forms.DialogResult.Cancel)//点击取消或者关闭 { return;//直接退出,撤销这次关闭程序的事件。
} } if (this.TabCount == 1)//是最后⼀个选项卡,直接关闭⽗界⾯,即画图界⾯ { father.DisposeForTabControl(true); } else//不是最后⼀
个 { this.TabPages.Remove(this.SelectedTab); } } } #endregion #region 右键选中 else if (e.Button == MouseButtons.Right) // 右键选中 { for (int i = 0; i <
this.TabPages.Count; i++) { TabPage tp = this.TabPages[i]; if
(this.GetTabRect(i).Contains(new Point(e.X, e.Y))) { this.SelectedTab = tp; break; } } } #endregion #region 中键选中关闭 else if (e.Button == MouseButtons.Middle)//⿏标中键关闭 { for (int i = 0; i < this.TabPages.Count; i++) { TabPage tp = this.TabPages[i]; if (this.GetTabRect(i).Contains(new Point(e.X, e.Y)))//找到后,关闭
{ this.SelectedTab = tp; string temp = tp.Text; if (temp[temp.Length - 5] == '*')//有变化才保存 { //确认是否保存VSD⽂档到ft_doc_Path DialogResult response = MessageBox.Show("是否保存故障树" + + "到图形⽂件", "请确认",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (response == System.Windows.Forms.DialogResult.Yes)//确认保
存 { axDrawingControl1.Document.SaveAs(GlobalVariables.ft_doc_Path + axDrawingControl1.Document.Title + ".vsd");//保存当前⽂档到⽂件夹 string datetime =
DateTime.Now.ToString();//获取当前时间 helpTool.saveVsdDB(axDrawingControl1.Document.Title, datetime);//保存vsd⽂档到数据库 helpTool.setDatetimeToXml(axDrawingControl1.Document.Title, datetime);//如果信息已存在则将xml中的⽇期更新,如果不存在直接插⼊ this.SelectedTab.Text =
temp.Substring(0, temp.Length - 5) + " ";//保存后取消星号标志,还原为没变化的时候的样式 } else if (response == System.Windows.Forms.DialogResult.Cancel)//点击取消或者关闭 { return;//直接退出,撤销这次关闭程序的事件。
} } if (this.TabCount == 1)//是最后⼀个选项卡,直接关闭⽗界⾯,即画图界⾯ { father.DisposeForTabControl(true);
} else//不是最后⼀个 { this.TabPages.Remove(this.SelectedTab); }
break; } } } #endregion } }
实现关闭按钮的关键代码是重写OnDrawItem(DrawItemEventArgs e)⽅法:
复制代码代码如下:protected override void OnDrawItem(DrawItemEventArgs e)//重写绘制事件。
{ Graphics g = e.Graphics; Rectangle r = GetTabRect(e.Index); if (e.Index == this.SelectedIndex) //当前选中的Tab页,设置不同的样式以⽰选中 { Brush selected_color = Brushes.Gold; //选中的项的背景⾊
g.FillRectangle(selected_color, r); //改变选项卡标签的背景⾊ string title = this.TabPages[e.Index].Text + "
"; g.DrawString(title, this.Font, new SolidBrush(Color.Black), new PointF(r.X + 3, r.Y + 6));//PointF选项卡标题的位置 r.Offset(r.Width - iconWidth - 3, 2); g.DrawImage(icon, new Point(r.X - 2, r.Y + 2));//选项卡上的图标的位置fntTab = new System.Drawing.Font(e.Font, FontStyle.Bold); } else//⾮选中的 {
g.FillRectangle(biaocolor, r); //改变选项卡标签的背景⾊ string title = this.TabPages[e.Index].Text + " ";
g.DrawString(title, this.Font, new SolidBrush(Color.Black), new PointF(r.X + 3, r.Y + 6));//PointF选项卡标题的位置
r.Offset(r.Width - iconWidth - 3, 2); g.DrawImage(icon, new Point(r.X - 2, r.Y + 2));//选项卡上的图标的位置 } }
其中的if-else是⽤来判断当前选项卡是否是选中的,使选中的颜⾊和未选中的不⼀样,项⽬中不需要的可以去除。
具体实现关闭功能的原理是重写protected override void OnMouseClick(MouseEventArgs e)⽅法,左键单击会触发对应事件,判断单击的区域位置是否在关闭按钮的区域,实现关闭功能。
另外有对中键和右键的处理,根据你的项⽬,修改对应按钮事件下的代码即可。
复制代码代码如下:
protected override void OnMouseClick(MouseEventArgs e)
{
#region 左键判断是否在关闭区域
if (e.Button == MouseButtons.Left)
{
Point p = e.Location;
Rectangle r = GetTabRect(this.SelectedIndex);
r.Offset(r.Width - iconWidth - 3, 2);
r.Width = iconWidth;
r.Height = iconHeight;
if (r.Contains(p)) //点击特定区域时才发⽣
{
string temp = this.SelectedTab.Text;
if (temp[temp.Length - 5] == '*')//有变化才保存
{
//确认是否保存VSD⽂档到ft_doc_Path
DialogResult response = MessageBox.Show("是否保存故障树" + + "到图形⽂件", "请确认", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response == System.Windows.Forms.DialogResult.Yes)//确认保存
{
axDrawingControl1.Document.SaveAs(GlobalVariables.ft_doc_Path + axDrawingControl1.Document.Title + ".vsd");//保存当前⽂档到⽂件夹
string datetime = DateTime.Now.ToString();//获取当前时间
helpTool.saveVsdDB(axDrawingControl1.Document.Title, datetime);//保存vsd⽂档到数据库
helpTool.setDatetimeToXml(axDrawingControl1.Document.Title, datetime);//如果信息已存在则将xml中的⽇期更新,如果不存在直接插⼊
this.SelectedTab.Text = temp.Substring(0, temp.Length - 5) + " ";//保存后取消星号标志,还原为没变化的时候的样式
}
else if (response == System.Windows.Forms.DialogResult.Cancel)//点击取消或者关闭
{
return;//直接退出,撤销这次关闭程序的事件。
}
}
if (this.TabCount == 1)//是最后⼀个选项卡,直接关闭⽗界⾯,即画图界⾯
{
father.DisposeForTabControl(true);
}
else//不是最后⼀个
{
this.TabPages.Remove(this.SelectedTab);
}
}
}
#endregion
#region 右键选中
else if (e.Button == MouseButtons.Right) // 右键选中
{
for (int i = 0; i < this.TabPages.Count; i++)
{
TabPage tp = this.TabPages[i];
if (this.GetTabRect(i).Contains(new Point(e.X, e.Y)))
{
this.SelectedTab = tp;
break;
}
}
}
#endregion
#region 中键选中关闭
else if (e.Button == MouseButtons.Middle)//⿏标中键关闭
{
for (int i = 0; i < this.TabPages.Count; i++)
{
TabPage tp = this.TabPages[i];
if (this.GetTabRect(i).Contains(new Point(e.X, e.Y)))//找到后,关闭
{
this.SelectedTab = tp;
string temp = tp.Text;
if (temp[temp.Length - 5] == '*')//有变化才保存
{
//确认是否保存VSD⽂档到ft_doc_Path
DialogResult response = MessageBox.Show("是否保存故障树" + + "到图形⽂件", "请确认", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response == System.Windows.Forms.DialogResult.Yes)//确认保存
{
axDrawingControl1.Document.SaveAs(GlobalVariables.ft_doc_Path + axDrawingControl1.Document.Title + ".vsd");//保存当前⽂档到⽂件夹
string datetime = DateTime.Now.ToString();//获取当前时间
helpTool.saveVsdDB(axDrawingControl1.Document.Title, datetime);//保存vsd⽂档到数据库
helpTool.setDatetimeToXml(axDrawingControl1.Document.Title, datetime);//如果信息已存在则将xml中的⽇期更新,如果不存在直接插⼊
this.SelectedTab.Text = temp.Substring(0, temp.Length - 5) + " ";//保存后取消星号标志,还原为没变化的时
候的样式
}
else if (response == System.Windows.Forms.DialogResult.Cancel)//点击取消或者关闭
{
return;//直接退出,撤销这次关闭程序的事件。
}
}
if (this.TabCount == 1)//是最后⼀个选项卡,直接关闭⽗界⾯,即画图界⾯
{
father.DisposeForTabControl(true);
}
else//不是最后⼀个
{
this.TabPages.Remove(this.SelectedTab);
}
break;
}
}
}
#endregion
}
写完之后如何使⽤呢
在你的窗体上拖⼀个TabControl,然后打开对应窗体代码⽂件的.Designer.cs⽂件⾥找到private void InitializeComponent()⽅法,然后找到⾥⾯对应的TabControl的定义语句即 this.TabControl =。
改成this.TabControl = new MyTabControl();如果想传参,就在前⾯重写MyTabControl时加⼊带参的构造函数(我的就带有参数)。
值得⼀提的是.Designer.cs⽂件⾥找到private void InitializeComponent()⽅法都是程序根据你的可视化界⾯设计⾃动⽣成的,所以每次你在可视化的设计环境下重新编辑了,这⾥就会重新⽣成,所以你得⼿动再次改⼀下this.TabControl = new MyTabControl();
我的程序效果如下。