轉帖|其它|編輯:郝浩|2011-04-18 13:18:00.000|閱讀 889 次
概述:ComboBox是一個很有用的控件,該控件基本在任何一套UI控件包中都屬于必須提供的必備基礎控件,同時它的實現也很值得學習.
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
ComboBox是一個很有用的控件,該控件基本在任何一套UI控件包中都屬于必須提供的必備基礎控件,同時它的實現也很值得學習.
所謂的“與ComboBox有相似行為”,我主要是指以下幾點,為了描述方便,我把此類控件分為兩部分,沒有下拉時,顯示的區域稱為主控件,下拉時,下拉區域稱為彈出控件.
1、彈出控件可以緊跟主控件的周圍.
2、彈出控件必須在最大范圍內不被父容器裁剪.比如,如果是Win32或者WinForm的ComboBox,它們的彈出控件是可以超出所在程序的窗口范圍的(可以把控件放到窗體的底部試試),僅受制于最頂級的窗口——桌面. Silverlight中的ComboBox也可以超出任何父容器,僅受制于最外層的容器——瀏覽器窗口(準確的說應該是Silverlight Plug-in所代表的范圍,不過一般都把這個范圍充滿整個瀏覽器的客戶區)
3、彈出控件彈出時,主控件需要可以做到不丟失輸入焦點
4、在主控件和彈出控件的顯示范圍之外點擊鼠標,下拉控件需要可以自動關閉
如果要做到以上的要求,在不同的UI框架上(這里我把win32的UI部分也稱為UI框架),做法不盡相同.
要求1:意味著必須能獲取主控件相對于最頂級窗口客戶區的絕對坐標.
在Winform中,控件的布局都是采取相對于父容器的絕對定位,所以只需要沿著控件樹向上遍歷,把絕對坐標逐個疊加,即可.
在Silverlight中,布局方式比較豐富,這樣獲取絕對坐標反而變得困難,幸運的是MS提供了輔助類,使用方式如下:
GeneralTransform generalTransform = 控件名稱.TransformToVisual(null);
Point point = generalTransform.Transform(new Point());
參考文章://www.kirupa.com/blend_silverlight/absolute_position_transformtovisual.htm
要求2:Winform中,所有的控件都會被外層Form所裁剪,要做到不被裁剪,可以用一個隱藏了標題欄的Form來模擬彈出控件.
Silverlight中,可以借助自帶的Popup控件實現
要求3:Winform中,因為采用Form來模擬彈出控件,默認情況下,在Form被顯示時,主控件肯定會失去焦點,因為這個時候焦點會轉移到這個新顯示的Form上,要讓主控件不丟失焦點,那么在創建Form是,需要使用WS_CHILDWINDOW樣式來創建,這樣創建出來的窗體不會搶奪輸入焦點,那么焦點就不會發生轉移.
Silverlight中,因為彈出控件是一個真實的控件,所以只需要把控件的IsEnable屬性設置為false,控件就不會接收焦點
要求4:在彈出窗口被顯示時,捕獲鼠標,這樣如果鼠標點擊主控件和彈出控件之外的區域,就可以收到通知,進而關閉彈出控件.注意,捕獲鼠標在WPF中和Silverlight中并不一致,WPF中使用System.Windows.Input.Mouse.Capture()來捕獲鼠標,而Silverlight(目前版本4)沒有這個類,而是使用UIElement的成員函數CaptureMouse()來執行捕獲.
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園