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