C# 重写ComboBox实现下拉任意组件

一、需求

C#种的下拉框ComboBox不支持下拉复选框列表与下拉树形列表等,系统中需要用到的地方使用了第三方组件,现在需要将第三方组件替换掉。

二、设计

基本思路:重写ComboBox,将原生的下拉部分屏蔽,使用toolStripDropDown制作下拉弹出

三、问题解决

1.     问题:toolStripDropDown中放toolStripControlHost时会有边框产生,同时CheckedListBox的duck为full时底端会有很大空白

解决:

toolStripControlHost.Margin = Padding.Empty;

toolStripControlHost.Padding = Padding.Empty;

toolStripControlHost.AutoSize = false;

toolStripDropDown.Padding = Padding.Empty;

CheckedListBox设置属性IntergralHeight为false

2.     问题:BorderStyle对于不同组件的显示效果不同,下拉部分边缘显示效果不好

解决:将组件BorderStyle统一设为None,再放入panel中,Panel重绘边线与背景后加入toolStripControlHost

3.     问题:下拉部分需要实现可拖动大小

解决:通过MouseDown、MouseLeave、MouseMove三个事件配合Cusor的位置来实现鼠标拖动改变组件大小,设置Label文字内容为"◢"作为拖动的指示

4.     问题:拖动时组件闪烁严重

解决:使用双缓存,重写ToolStripDropDown中的CreateParams,设置cp.ExStyle |= 0x02000000;//双缓存

5.     问题:下拉焦点问题,点击下拉后下拉部分没有获取焦点,导致右下角拖放标志捕捉不到鼠标

解决:ComboBox在事件OnDropDown之后可能还会进行某些操作导致再次获取焦点,所以要将设置下拉部分焦点的动作写在OnMouseClick的事件中

6.     问题: ComboBox的文本输入问题

解决:当DropDownStyle为DropDown时,ComboBox可输入,这是不太合适的,但是无法设置不能输入。

当DropDownStyle为DropDownList时,可以实现不能手动输入,但是不能直接对Text赋值,需要New一个Item再将Item的值选中实现Text显示

7.     问题: ComboBox的下拉部分隐藏

解决:当需要隐藏原生下拉部分时,设置DropDownHeight=1即可

8.     问题: 下拉部分存在时点击下拉框,关闭下拉

解决:由于toolStripDropDown的关闭事件在ComboBox的点击事件之前,所以不能通过toolStripDropDown的状态来设计。

我的方法是,设置一个全局变量isCursorOnComboBox,用于判断关闭下拉部分时光标是否在comboBox上。在toolStripDropDown的Closed事件中改变这个值,在点击下拉事件中根据这个值来决定是否要生成下拉部分。

9.     问题: 当不生成下拉部分,没有失去焦点时,ComboBox点击一次后处于下拉状态,需要再点击一次才恢复正常

解决:通过模拟键盘输入Enter键强行恢复

10.问题: CheckedListBox选中后显示选中Items的内容

解决:主要问题在事件的选择上,如果写在selected等事件中时,与复选框的选择有出入,不适合(如双击等),写在ItemCheck事件上时发现是在选中前,导致正在选的Item值判断延迟。

所以最好选择与Check直接挂钩的ItemCheck事件,同时对正在Check的Item进行特殊处理,使用异或(!=)运算。

11.问题: 兼容性,其他组件的下拉支持

解决:在TypeC中添加Other条目,当下拉类型为Other时,设置DropDown内容为普通Control,调用方可以通过设置SetDropDown(Control)来设置要显示的组件内容。

12.问题: 下拉面板颜色在Windows不同主题下显示问题

解决:由于在Windows的经典模式下,使用Sytem.XXX 调用不到颜色,导致下拉框颜色显示不出。

绘制时使用Color.XXX中的颜色,在不同系统模式下显示都正常。

四、使用方法

1.     放下拉复选列表

①   界面拖出HsComboBox

②   设置属性CtlType = CheckedListBox

③   (可选)代码调用hsComboBox.SetDropDown(CheckedListBox)重新设置内容

④   代码调用hsComboBox. CheckedListBox可获取组件

2.     放下拉树形

⑤   界面拖出HsComboBox

⑥   设置属性CtlType = TreeView

⑦   (可选)代码调用hsComboBox.SetDropDown(TreeView)重新设置内容

⑧   代码调用hsComboBox. TreeView可获取组件

3.     做普通ComboBox

⑨   界面拖出HsComboBox

⑩   设置属性CtlType = Null

4.     放任意Control

?   界面拖出HsComboBox

?   设置属性CtlType = Other

?   代码调用hsComboBox.SetDropDown(Control)放入内容

?   代码调用hsComboBox.Control可获取组件

五、注意要点

1.     ComboBox的Text设置

调用函数ShowText()设置Text内容,可用于自定义组件的事件等

2.     DropDownStyle

为禁止文本手工输入,DropDownStyle将在构造函数中设为DropDownList

Demo下载:

http://files.cnblogs.com/files/peifei/HsComboBoxDemo.rar

时间: 2024-10-15 01:49:02

C# 重写ComboBox实现下拉任意组件的相关文章

自绘制HT For Web ComboBox下拉框组件

传统的HTML5的下拉框select只能实现简单的文字下拉列表,而HTforWeb通用组件中ComboBox不仅能够实现传统HTML5下拉框效果,而且可以在文本框和下拉列表中添加自定义的小图标,让整个组件看起来更直观,今天我就如何制定ComboBox自定义下拉框做一番探讨. 首先我们先来目睹下效果:   看起来跟普通的ComboBox好像也没什么特殊的,是的,按照规范的ComboBox设计,完全可以实现同样的效果,但是今天的主要任务并不是讨论有多少实现方案,今天的首要任务是介绍HT for We

Android打造通用的下拉刷新组件

还记得上一篇 blog 的内容吗?如果不记得建议先去了解一下,Android 事件处理全面剖析 ,因为下拉刷新需要用到手势的处理,而上一篇文章中,对事件处理做了很详细的说明,了解了事件的处理机制,对理解本篇文章有很大的帮助.好了,这里就当大家都已经对事件处理有了一定的了解,开始我们的下拉刷新征程. 还是老规矩,先上效果图,再根据效果图来分析实现的原理: 一 .分析原理 我们都知道,listView 控件为我们提供了 addHeaderView.和 addFootView 的方法,我们通过此方法可

自定义View——利用下拉刷新组件实现上拉加载

注:本文demo已经提交github,地址完整代码如下,demo工程已经上传至GitHub, github地址https://github.com/wsclwps123/UpLoadSwipeRefreshLayout 感谢大家支持! 在Android开发中,我们经常会用到列表下拉刷新和上拉加载的功能. Google在support.v4包中提供了一个组件可以用来进行下来刷新,这个组件是SwipeRefreshLayout. 下面我们来看一下这个组件的使用: 在布局文件中加上xml代码 <and

React Native控件之PullToRefreshViewAndroid下拉刷新组件讲解

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50664323 本文出自:[江清清的博客] (一)前言 今天我们一起来看一下PullToRefreshViewAndroid下拉刷新组件讲解以及使用实例 刚创建的React Native技术交流群(282693535),欢迎各位大牛,React Native技术爱好者加入交流!同时博客左侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送! 该PullToRefr

spinner下拉框组件

方法一代码如下: <string-array name="city_name"> <item>浙江</item> <item>上海</item> <item>北京</item> </string-array> <Spinner android:id="@+id/citySelect" android:layout_width="fill_parent&qu

打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)

前言 最近在做项目时,使用了一个开源的下拉刷新ListView组件,极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(ListView.GridView等)通用的下拉刷新.上拉自动加载的组件.但是这种通过修改Margin的形式感觉不是特别的流畅,因此在这漫长的国庆长假又花了点时间用另外的原理实现了一遍,特此分享出来. 基本原理 原理就是自定义一个ViewGroup,将Header View, Content View,

第二百二十四节,jQuery EasyUI,ComboGrid(数据表格下拉框)组件

jQuery EasyUI,ComboGrid(数据表格下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.方法列表 本节课重点了解 EasyUI 中 ComboGrid(数据表格下拉框)组件的使用方法,这个组件 依赖于 Combo(自定义下拉框)和 DataGrid(数据表格)组件. 一.加载方式 class 加载方式 <select id="box" class="easyui-combogrid" name="dept" sty

Google自己的下拉刷新组件SwipeRefreshLayout

SwipeRefreshLayout SwipeRefreshLayout字面意思就是下拉刷新的布局,继承自ViewGroup,在support v4兼容包下,但必须把你的support library的版本升级到19.1. 提到下拉刷新大家一定对ActionBarPullToRefresh比较熟悉,而如今google推出了更官方的下拉刷新组件,这无疑是对开发者来说比较好的消息.利用这个组件可以很方便的实现Google Now的刷新效果,见下图: 主要方法 setOnRefreshListene

Android内置下拉刷新组件SwipeRefreshLayout

也许下拉刷新之前,你可能会使用一些第三方的开源库,例如PullToRefresh, ActionBar-PullToRefresh等待,但现在有的正式组成部分---SwipeRefreshLayout,SwipeRefreshLayout是Google在support v4 19.1版本号的library更新的一个下拉刷新组件,使用起来非常方便,能够非常方便的实现Google Now的刷新效果. 使用官方自带的控件能够保证通用性以及风格.SwipeRefreshLayout是继承ViewGrou