微軟套裝的ComboBox本身就提供了AutoCompete功能,隻要設定AutoCompleteMode和AutoCompleteSource屬性即可,而且功能還是很強大的。但是…還是滿足不了我的要求。
1. AutoComplete時下拉框隻顯示近似比對的項,不是顯示全部項并自動定位到比對項。
2. 當輸入的内容找不到比對項時,還允許使用者錄入,并且SelectedIndex将為-1, 同時SelectedValue為null。
但是在多數情況下,我們是不允許使用者輸入選項以外的内容,輸入隻是進行lookup。而且SelectedIndex變為-1也不是所期盼的。是以,擴充ComboBox做了一個自定義控件。
1. 當擷取焦點時全部文本預設是選中的,這時使用者錄入的内容就會代替全部内容去lookup。
2. 如果找到比對項,就定位到比對項,并且将文本的選中區域從使用者錄入内容向後選中;沒有比對項則錄入無效。
3. 當使用者倒退或Del時,如果沒有找到比對項則隻是将文本的選中區域擴大。
4. 當使用者删除了内容時,如果沒有找到比對項則删除無效。如果使用者要把内容全部删掉,就會跟據LimitedToList 屬性來決定是否清空文本,當然也就是是否将SelectedIndex設定為-1。
5. 不允許Ctrl+X,最主要的原因是我在OnKeyPress事件中停止事件繼續冒泡,這樣剪切的内容并沒有複制到剪切闆。
6. 不允許ESC,原因是當下拉清單打開時ESC會将SelectedIndex恢複,但是使用者錄入比對的文本不會恢複。
可能你注意到OnValidating方法。與OnLeave方法不同OnValidating方法不僅在失去焦點時會被調用,在使用者使用快捷鍵觸發按鈕事件時也會被調用。後者對我來說更重要,因為使用者都通過按鈕的快捷鍵來完成儲存操作,而快捷鍵并不會使ComboBox命運焦點,即不會調用OnLeave方法。
做這個控件還發生了一個波折,最初我是在OnTextChanged方法中完成比對選中的,并且沒有添加OnValidating方法,在我的本機(Windows 7)測試通過(當然除了使用者按快捷鍵的情況)。但是使用者使用的環境是XP和Windows 2003,Lookup比對完成後ComboBox的SelectedIndex競然是-1。
當然如果加上了OnValidatin方法也可以解決,但是使用overrid OnTextChanged的解決方案會引發多次TextChanged事件,最終還是改用了OnKeyPress方法。
順便說一下,如果要在LookupComboBox的SelectedIndexChanged事件中想彈出一個确認對話框,讓使用者選是否或取消的那種,在彈框前要調用ComboBox.DroppedDown = false,這樣ComboBox會接受lookup的最終結果。
如果你有更好的解決方案,請指教。