ComponentArt控件分析之ComboBox(1)

本文详细解析了ComponentArt的ComboBox控件实现原理,包括HTML结构、JavaScript交互、CSS样式等关键技术点,并介绍了如何逐步构建复杂的UI控件。

ComponentArt相信很多人都用过.功能比较强大,而且使用方便.最近可能要用到这套控件.所以顺便要学习一下这套控件是如何实现的.

我并不会贴一下代码就了事,也不可能一篇就把一个控件就讲完.这样的话,一个商业控件也太简单了.

还是让我们来一起来慢慢的分析.我会尽量凭自己能力把细节都写出来

我们先从ComboBox入手


一.效果图
先看下效果



图一

ComboBox特性:
与DropDownList相比,可以自己输入文本,但HTML未提供这样的标签,所以只能利用现有的标签来模拟.

上面为截图,让我们来看下生成的HTML代码,此部分为局部代码.包含了两个集合

None.gif<table id="ComboBox2" class="comboBox" cellpadding="0" cellspacing="0" onmouseout="ComboBox2.HandleInputMouseOut()" onmouseover="ComboBox2.HandleInputMouseOver()" style="display:inline-block;width:200px;">
None.gif
<tr>
None.gif
<td width="100%" id="ComboBox2_TextBox"><input id="ComboBox2_Input" name="ComboBox2_Input" autocomplete="off" onsubmit="return false;" type="text" class="comboTextBox" onfocus="ComboBox2.HandleFocus()" onblur="ComboBox2.HandleBlur(event)" onkeydown="ComboBox2.HandleKeyPress(event,this)" style="display:none;" /></td><td><img onmouseup="ComboBox2.HandleDropMouseUp(event,this)" onmousedown="ComboBox2.HandleDropClick(event,this)" src="images/drop.gif" id="ComboBox2_DropImage" style="display:block;" /></td>
None.gif
</tr>
None.gif
</table>
None.gif
<div class="comboDropDown" id="ComboBox2_DropDown" style="display:none;">
None.gif
<table cellpadding="0" cellspacing="0" border="0" width="100%">
None.gif
<tr>
None.gif
<td><div id="ComboBox2_DropDownContent" onscroll="ComboBox2.HandleScroll(event,this)" onmousedown="ComponentArt_CancelEvent(event)" onmouseup="ComboBox2.HandleMouseUp(event,this)">
None.gif
None.gif
</div></td>
None.gif
</tr>
None.gif
</table>
None.gif
</div>



(1)一个table  里面存在着一个文本框和一个图片,看下图


图二
(2)当选中右边的图片时,会出现一个下拉框,即把隐藏的div呈现出来,可以看到其初始化为隐藏,
style="display:none;".看下图


图三

两个组合在一起就形成了一个ComboBox控件

二.复杂控件实现步骤

我们先不讨论其代码,先来分析

复杂控件实现步骤(我自己认为的):

1.先不要马上开始写后台编码

一个服务器控件呈现到页面上以后,最终是HTML代码,这个控件肯定也夹杂着javascript,看到此效果,应该先把思路转回来,问自己能否抛开服务器控件这个概念写出一个控件(以后可以重构)

2.封装javascript

javascript很重要,得到数据以后,我们就需要这门语言帮助处理.由于是控件,必须具有重用性,在页面上所做的事情大部分都是加载js文件和调用代码.现在有很多框架供你选择,如asp.net ajax,prototype.我们需要以面向对象编程的形式来实现.看下ComboBox前台js的调用.

ContractedBlock.gifExpandedBlockStart.gif
None.gif<script type="text/javascript">
None.gif
//<![CDATA[
ExpandedBlockStart.gifContractedBlock.gif
/**//*** ComponentArt.Web.UI.ComboBox 2007_1_1512_2 ComboBox2 ***/
ExpandedBlockStart.gifContractedBlock.gif
function ComponentArt_Init_ComboBox2() dot.gif{
InBlock.gif
if(!(window.ComponentArt_Page_Loaded && window.ComponentArt_ComboBox_Kernel_Loaded && window.ComponentArt_ComboBox_Support_Loaded && window.ComponentArt_Utils_Loaded && window.ComponentArt_ComboBox_Keyboard_Loaded && window.ComponentArt_Keyboard_Loaded))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{setTimeout('ComponentArt_Init_ComboBox2()', 100); return; }
InBlock.gif
InBlock.gifwindow.ComboBox2 
= new ComponentArt_ComboBox('ComboBox2');
InBlock.gifComboBox2.Data 
= [[['Text','a'],['Value','b']],[['Text','b'],['Value','c']],[['Text','c'],['Enabled',0],['Value','b']],[['CssClass','comboItemHover'],['Text','d'],['Value','c'],['Id','ComboBoxItem1']],[['Text','a'],['Value','b']],[['Text','b'],['Value','c']],[['Text','c'],['Enabled',0],['Value','b']],[['CssClass','comboItemHover'],['Text','d'],['Value','c'],['Id','ComboBoxItem2']],[['Text','a'],['Value','b']],[['Text','b'],['Value','c']],[['Text','c'],['Enabled',0],['Value','b']],[['CssClass','comboItemHover'],['Text','d'],['Value','c'],['Id','ComboBoxItem3']],[['Text','a'],['Value','b']],[['Text','b'],['Value','c']],[['Text','c'],['Enabled',0],['Value','b']],[['CssClass','comboItemHover'],['Text','d'],['Value','c'],['Id','hello']]];
ExpandedSubBlockStart.gifContractedSubBlock.gifComboBox2.Postback 
= function() dot.gif{ __doPostBack('ComboBox2','') };
InBlock.gifComboBox2.AutoComplete 
= 1;
InBlock.gifComboBox2.CacheSize 
= 200;
InBlock.gifComboBox2.CallbackPrefix 
= 'http://localhost:49831/Default.aspx?Cart_ComboBox2_Callback=yes';
InBlock.gif
ComboBox2.ClientEvents = null;
InBlock.gifComboBox2.ClientTemplates 
= [];
InBlock.gifComboBox2.ControlId 
= 'ComboBox2';
InBlock.gifComboBox2.CollapseSlide 
= 2;
InBlock.gifComboBox2.CollapseDuration 
= 200;
InBlock.gifComboBox2.CssClass 
= 'comboBox';
InBlock.gifComboBox2.DropDownHeight 
= 0;
InBlock.gifComboBox2.DropDownPageSize 
= 10;
InBlock.gifComboBox2.DropDownResizingMode 
= 'Off';
InBlock.gifComboBox2.DropDownResizingStyle 
= 'Live';
InBlock.gifComboBox2.DropDownWidth 
= 0;
InBlock.gifComboBox2.DropActiveImageUrl 
= 'images/drop_hover.gif';
InBlock.gifComboBox2.DropImageUrl 
= 'images/drop.gif';
InBlock.gifComboBox2.DropHoverImageUrl 
= 'images/drop_hover.gif';
InBlock.gifComboBox2.Enabled 
= 1;
InBlock.gifComboBox2.EnableViewState 
= 1;
InBlock.gifComboBox2.ExpandDirection 
= 0;
InBlock.gifComboBox2.ExpandDuration 
= 200;
InBlock.gifComboBox2.ExpandSlide 
= 2;
InBlock.gifComboBox2.FilterCacheSize 
= 10;
InBlock.gifComboBox2.FocusedCssClass 
= 'comboBoxHover';
InBlock.gifComboBox2.HoverCssClass 
= 'comboBoxHover';
InBlock.gifComboBox2.ItemCount 
= 16;
InBlock.gifComboBox2.ItemCssClass 
= 'comboItem';
InBlock.gifComboBox2.ItemHoverCssClass 
= 'comboItemHover';
InBlock.gifComboBox2.LoadingText 
= 'Loadingdot.gif';
InBlock.gifComboBox2.KeyboardEnabled 
= 1;
InBlock.gifComboBox2.RunningMode 
= 0;
InBlock.gifComboBox2.SelectedIndex 
= -1;
InBlock.gifComboBox2.SelectedItemCssClass 
= 'comboItemHover';
InBlock.gifComboBox2.TextBoxCssClass 
= 'comboTextBox';
InBlock.gifComboBox2.TextBoxEnabled 
= 1;
InBlock.gifComboBox2.TextBoxFocusedCssClass 
= 'comboTextBox';
InBlock.gifComboBox2.TextBoxHoverCssClass 
= 'comboBoxHover';
InBlock.gifComboBox2.InitKeyboard();
InBlock.gif
InBlock.gifComboBox2.Initialize();
ExpandedBlockEnd.gif}

None.gifComponentArt_Init_ComboBox2();
None.gif
//]]>
None.gif
</script>

3.列出控件基本功能和扩展功能
不要一步到位做到,慢慢完善

4.封装成控件

这里需要权衡下,代码由服务器产生还是由dom来解析,让我们看下上面的下拉框的html代码,我们并没有看到数据,而是通过dom来解析的.服务器控件主要用于呈现初始化数据和数据交互

上面讲的可能还不到位.但还是需要注意的

三.基本功能分析


1.为子标签(这里并非只复合控件,只是为了思路清晰)提供ID属性,这样的话,我们才可以用javascript进行操作.而且这样易于扩展

ComboBox2,ComboBox2_TextBox,ComboBox2_Input,ComboBox2_DropImage,ComboBox2_DropDown,ComboBox2_DropDownContent.

2.用css定义样式
ComponentArt的ComboBox具有很多的样式属性,可以把内部看成是子控件,但其抛弃了子控件Style属性的做法,全部改用css样式来控制.
因为子标签有了ID属性,我们只需要设置属性,然后逻辑交给javascript处理.
具体样式可以参考Api文档

3.展开和关闭下拉框,即_DropImage客户端事件的触发了

4.将值填充到_Input文本框上

5.初始化下拉列表数据,这里需要跟数据库交互,需要设计,可以先暂时用测试数据来代替

6.预加载  这是一个小技巧,如,你要预先加载图片,你可以把其高和宽设置为0就可以了.
看下代码
None.gif<div style="position:absolute;top:0px;left:0px;visibility:hidden;"><img src="images/drop_hover.gif" width="0" height="0" alt="" />
None.gif
<img src="images/drop.gif" width="0" height="0" alt="" />
None.gif
<img src="images/drop_hover.gif" width="0" height="0" alt="" />
None.gif
</div>


以上为基本功能.难点在于3和5.所以先不谈这些.让我们来把基本的先解决掉.再看下html代码,我们看到标签上有很多的事件如下

控件本身事件
onmouseout="ComboBox2.HandleInputMouseOut()"       更改样式
onmouseover="ComboBox2.HandleInputMouseOver()"   更改样式

_Input事件

onfocus="ComboBox2.HandleFocus()"                            更改样式并选中文本框值
onblur="ComboBox2.HandleBlur(event)"                         更改样式
onkeydown="ComboBox2.HandleKeyPress(event,this)"   //先不管

_DropImage

onmouseup="ComboBox2.HandleDropMouseUp(event,this)"   更改样式
onmousedown="ComboBox2.HandleDropClick(event,this)"     //展开下拉框

_DropDown

onmousemove="ComboBox2.HandleMouseMove(event,this)" 
onmouseout="ComboBox2.HandleMouseOut(event,this)"
onmousedown="ComboBox2.HandleMouseDown(event,this)"

_DropDownContent

onmousedown="ComponentArt_CancelEvent(event)"
onmouseup="ComboBox2.HandleMouseUp(event,this)"

_item_0(此为列表项)

onmousedown="ComponentArt_CancelEvent(event)"
onclick="ComboBox2.HandleClick(event,this,0)"
onmouseout="ComboBox2.HandleItemMouseOut(event,this, 0);"       更改样式
onmouseover="ComboBox2.HandleItemMouseOver(event,this, 0);"   更改样式


先到这里,下次继续
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值