• TabControl增强版


    效果图:

    NET提供TabControl控件的选项卡太丑陋,功能也太少了,虽然它允许你重写它的选项卡绘制方法来进行美化,但是它是使用默认win32 api 去创建和管理选项卡的,能修改的范围有限。因此我重新用c#开发开发该控件,选项卡部分逻辑完全由c#语言来管理,这也是这个控件的重点。

    微软说开源.NET,我发现他没有百分百开源,至少在ndp开源项目找不到System.Design的开源代码。我通过查看 “ndp开源项目” 和反编译 “控件设计器项目” 参考他的设计来重新编写了增强版的TabControl控件。这个控件有两个程序集 :

    WinformControlLibraryExtension.ComplexityPropertys”  (控件复杂属性定义)

    WinformControlLibraryExtension”  (控件)

    要使用 TabControlUpGradesExt 控件 ,你必须要手动添加“WinformControlLibraryExtension”到你的VS的工具箱。这个程序集可以用“项目方式”或“DLL”方式 引用到你的项目,如果添加后页面报错你要手动添加“WinformControlLibraryExtension.ComplexityPropertys” DLL到你项目引用里,因为这个程序集没有自动帮你添加到你的项目里。注意“WinformControlLibraryExtension.ComplexityPropertys” 这个项目只能通过编辑后“DLL”方式添加到你的项目里面。这是因为在这个程序集里面有 BackGauge.csRoundedCorner.cs 两个复杂属性机构体定义,因为如果是以“项目方式”添加“WinformControlLibraryExtension.ComplexityPropertys” 到你的项目,当你在VS设计器编辑好窗体保存时会报错,提示你自定义复杂属性无法序列化导致保存不了,最后窗体Designer.cs有代码丢失损坏。这是很严重的事。这个问题我看过国外论坛也有人遇过,因为在“项目方式”下引用,编译时产生了两个版本的WinformControlLibraryExtension.ComplexityPropertys 导致VS识别出错,他们问过团队,承认是VS的bug来的,说在之前某个版本已经修复了,但是我在vs2019还是出现这种情况。难道他们说修复后也只能通过DLL方式应用。

    TabControlUpGradesExt 控件和我以往写的控件有些区别,这些区别主要是“控件由父子两种控件组成”、“子控件的集合属性也和以往的简单类控件里的集合属性写法有区别”、“按照VS试图设计器提供的基类为父子控件编写对应的设计器”。 TabControlUpGradesExt 主体控件是基于 Control 控件基础类开发的。 TabPageUpGradesExt 子控件是继承 Panel 控件基础类开发的。

    设计图:

    该控件增加的功能包括以下

    1.菜单栏可以添加全局自定义按钮。

    2.选项卡的布局方式有3种:横向布局、纵向布局,垂直布局。

    3.每个选项可以添加:自定义图标、关闭按钮、自定义按钮。

    4.选项的文本显示方式有3种:横向显示、纵向显示,垂直显示。

    5.每个选项可以独立设置间距。

    6.选项预留绘制事件让开发者可以根据自身情况进一步美化控件。

    7.根据系统的缩放比例自动缩放控件防止失真。

     该控件文件包括以下

    ControlCommom.cs (控件通用工具类)
    WindowNavigate.cs (win 32 api 方法封装)
    DotsPerInchHelper.cs (系统缩放比例帮助类)

    CollectionEditorExt.cs (让设计器拥有编辑"集合属性"编辑功能)
    ColorEditorExt.cs(让设计器拥有编辑"透明颜色属性"功能)
    EmptyConverter.cs (让设计器拥有编辑"对象颜色属性"功能)
    TabControlUpGradesExtDesigner.cs (让设计器拥有编辑“TabControlUpGradesExt”控件)
    TabPageUpGradesExtDesigner.cs(让设计器拥有编辑“TabPageUpGradesExt”控件)

    BackGauge.cs (自定义左右边距复杂属性)
    BackGaugeConverter.cs (让设计器拥有编辑“自定义左右边距复杂属性”功能)
    RoundedCorner.cs (自定义圆角复杂属性)
    RoundedCornerConverter.cs(让设计器拥有编辑“自定义圆角复杂属性”功能)

    TabControlUpGradesExt.cs (控件中父控件)
    TabPageUpGradesExt.cs(控件中子控件)

     控件最复杂的地方就是每个部件Rectangle 的计算。控件选项卡逻辑原理大致如下:

    1.UpdateEveryOneTabItemSize() (计算每一个选项及内部部件的Size)
    2.UpdateMenuBarRectangle() (更新菜单区Rectangle、更新全局自定义按钮区域及部件Rectangle、更新导航栏区域及部件Rectangle和显示状态、更新TabItems的总显示区域)
    3.UpdateEveryOneTabItemRectangle()  (更新每个选项及内部部件Rectangle)
    4.ReplenishTabItemToRectangleForLeft()  (自动根据TabItems的总显示区判断是否把左边已隐藏的选项添加到显示区)
    5.ReplenishSelectTabItemToRectangle()  (自动把已选中选项显示在TabItems的总显示区中)
    6.UpdateTabMainDisplayRectangleByTabItemsDisplayRectangle()  (根据菜单Rectangle更新TabPage主体区域Rectangle)

    控件初始化:1、2、3、4、5、6
    控件ReSize:2、3、4、5、6
    导航栏按钮:3
    选项选中更改事件:5

           

    TabControlUpGradesExt控件新增的属性                     TabControlUpGradesExt控件新增事件                    TabPageUpGradesExt控件新增的属性 

     控件菜单布局效果:

    利用 MenuBarAlignment 、 TabItemVerticalLayout 、 TabItemTextVerticalLayout 属性可以进行以下布局:

     控件选项自定义绘制效果:

    通过 MenuBarDrawBackgroundBefore MenuBarDrawBackgroundAfter 、TabItemCreateCustomPathBeforeTabItemDrawBackgroundAfter 绘制事件可以让选项卡绘制出自定义风格。在绘制时要注意事件参数Graphics 属性Set访问器是公开的,这就意味你对Graphics的属性修改后要把它还原成原来值,不然他会影响控件的其他绘制。还有在计算要绘制范围时计算也要乘以系统当前的缩放比例 e.DPIScale.XScale ,不然你绘制出来的东西尺寸是不对的。

    控件选项小部件效果:

    选项的小部件包括:

    1.图标:可以统一设置显示状态,也可以独立设置选项的图标是否显示。

    2.自定义按钮:可以为每个选项添加不同数量的独立按钮,按钮分为“Button”、“CheckButton”两种。

    3.关闭按钮:可以统一设置显示状态,也可以独立设置选项的关闭按钮是否显示。还可以统一设置关闭按钮所在的位置。

    控件选项事件讲解:

    TabItemDeselecting (TabItem取消选中事件)
    TabItemDeselected (TabItem取消选后事件)
    TabItemSelecting (TabItem选中时事件)
    TabItemSelected (TabItem选中后事件)
    SelectedIndexChanged (TabItem选中索引更改后事件)

    当鼠标、键盘、代码设置SelectedIndex 来切换激活选项时触发事件顺序:

    TabItemDeselecting => TabItemDeselected => TabItemSelecting =>TabItemSelected => SelectedIndexChanged

    当移除选项卡时触发事件顺序:

    TabItemSelecting =>TabItemSelected => SelectedIndexChanged

    控件库的例子已整体发布到gitee,下载地址:https://gitee.com/tlmbem/tabcontrol 

  • 相关阅读:
    创建可管理的对象属性
    解析简单xml文档
    定义类的__slots__属性节省内存的开销
    读写json数据
    读写csv,excel文件数据
    常用的字符串处理方法
    sql中case when 的使用
    对字典的处理
    元组的元素命名
    列表,字典,集合按条件筛选
  • 原文地址:https://www.cnblogs.com/tlmbem/p/16186912.html
Copyright © 2020-2023  润新知