当前位置:  编程技术>.net/c#/asp.net

c#重写TabControl控件实现关闭按钮的方法

    来源: 互联网  发布时间:2014-10-17

    本文导语:  1.c#里面的TabControl控件没有关闭按钮,而且很难看。 2.有一些已经做好的第三方控件,但是收费。 3.由于我的故障树推理诊断项目在绘图的时候允许同时打开多个文档进行操作,就要实现类似于浏览器的多标签功能,而且要可...

1.c#里面的TabControl控件没有关闭按钮,而且很难看。

2.有一些已经做好的第三方控件,但是收费。

3.由于我的故障树推理诊断项目在绘图的时候允许同时打开多个文档进行操作,就要实现类似于浏览器的多标签功能,而且要可以关闭。

4.所以自己写一个类继承TabControl类,然后重写一些里面的方法即可实现。

5.特色:有关闭按钮,标签有背景颜色,选中的标签和没选中的颜色不一样,实现鼠标中键和右键的功能

先看我的项目中的完整代码,有很多代码是我的项目需要,可根据你的项目需求删减,核心的代码后面详细解释:

代码如下:

 ///
    /// 重写的TabControl控件 带关闭按钮
    ///
    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;
        }
        ///
        /// 设置父窗口
        ///
        /// 画图窗口
        public void setFather(Form_paint fp)
        {
            this.father = fp;
        }
        ///
        /// 重写的绘制事件
        ///
        ///
        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("是否保存故障树" + this.SelectedTab.Name + "到图形文件", "请确认", 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("是否保存故障树" + this.SelectedTab.Name + "到图形文件", "请确认", 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("是否保存故障树" + this.SelectedTab.Name + "到图形文件", "请确认", 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("是否保存故障树" + this.SelectedTab.Name + "到图形文件", "请确认", 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();


我的程序效果如下

 


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java Servlet实现Session创建存取以及url重写代码示例
  • why在重写equals时还必须重写hashcode方法分享
  • URL重写库 Rewrite
  • java方法重写实例分析
  • 强烈建议重写csdn,我已经是用adsl了,还!◎#¥¥%%……%
  • MBR被重写了,使用网上所说的命令怎么出错呢?
  • 急!u_boot无法重写下载??
  • 准备重写Click,应注意些什么?
  • 如何知道一个可重写光盘,是磁光型还是变相型?
  • Java的URL重写过滤器 UrlRewriteFilter
  • asp.net URL重写的方法参考
  • MBR重写问题
  • asp.net输出重写压缩页面文件的实例
  • asp.net使用URLRewriter.dll进行重写的方法举例
  • ThinkPHP中pathinfo的访问模式、路径访问模式及URL重写总结
  • URLRewriter.dll的url重写(伪静态)的简单例子
  • aspnet_isapi.dll实现无后缀名的url重写(伪静态)
  • ThinkPHP的URL重写问题
  • Request.RawUrl获取当前请求重写(UrlRewrite)Url的方法介绍
  • 浅析ThinkPHP中的pathinfo模式和URL重写
  • 在nginx中配置pathinfo模式支持thinkphp的URL重写


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3