一、需求
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
轉載于:https://www.cnblogs.com/peifei/p/5995357.html