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

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

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

我们先从ComboBox入手


一.效果图
先看下效果


ComponentArt控件分析之ComboBox(1)_css
图一

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

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

ComponentArt控件分析之ComboBox(1)_css_02<table id="ComboBox2" class="comboBox" cellpadding="0" cellspacing="0" onmouseout="ComboBox2.HandleInputMouseOut()" onmouseover="ComboBox2.HandleInputMouseOver()" style="display:inline-block;width:200px;">
ComponentArt控件分析之ComboBox(1)_css_02<tr>
ComponentArt控件分析之ComboBox(1)_css_02<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>
ComponentArt控件分析之ComboBox(1)_css_02</tr>
ComponentArt控件分析之ComboBox(1)_css_02</table>
ComponentArt控件分析之ComboBox(1)_css_02<div class="comboDropDown" id="ComboBox2_DropDown" style="display:none;">
ComponentArt控件分析之ComboBox(1)_css_02<table cellpadding="0" cellspacing="0" border="0" width="100%">
ComponentArt控件分析之ComboBox(1)_css_02<tr>
ComponentArt控件分析之ComboBox(1)_css_02<td><div id="ComboBox2_DropDownContent" onscroll="ComboBox2.HandleScroll(event,this)" onmousedown="ComponentArt_CancelEvent(event)" onmouseup="ComboBox2.HandleMouseUp(event,this)">
ComponentArt控件分析之ComboBox(1)_css_02
ComponentArt控件分析之ComboBox(1)_css_02</div></td>
ComponentArt控件分析之ComboBox(1)_css_02</tr>
ComponentArt控件分析之ComboBox(1)_css_02</table>
ComponentArt控件分析之ComboBox(1)_css_02</div>



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

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

ComponentArt控件分析之ComboBox(1)_sed_17
图三

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

二.复杂控件实现步骤

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

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

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

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

2.封装javascript

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

ComponentArt控件分析之ComboBox(1)_javascript_18ComponentArt控件分析之ComboBox(1)_sed_19
ComponentArt控件分析之ComboBox(1)_css_02<script type="text/javascript">
ComponentArt控件分析之ComboBox(1)_css_02//<![CDATA[
ComponentArt控件分析之ComboBox(1)_控件_22ComponentArt控件分析之ComboBox(1)_html_23/**//*** ComponentArt.Web.UI.ComboBox 2007_1_1512_2 ComboBox2 ***/
ComponentArt控件分析之ComboBox(1)_控件_22ComponentArt控件分析之ComboBox(1)_html_23function ComponentArt_Init_ComboBox2() ComponentArt控件分析之ComboBox(1)_sed_26{
ComponentArt控件分析之ComboBox(1)_css_27if(!(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))
ComponentArt控件分析之ComboBox(1)_javascript_28ComponentArt控件分析之ComboBox(1)_控件_29    ComponentArt控件分析之ComboBox(1)_sed_26{setTimeout('ComponentArt_Init_ComboBox2()', 100); return; }
ComponentArt控件分析之ComboBox(1)_css_27
ComponentArt控件分析之ComboBox(1)_css_27window.ComboBox2 = new ComponentArt_ComboBox('ComboBox2');
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.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']]];
ComponentArt控件分析之ComboBox(1)_javascript_28ComponentArt控件分析之ComboBox(1)_控件_29ComboBox2.Postback = function() ComponentArt控件分析之ComboBox(1)_sed_26{ __doPostBack('ComboBox2','') };
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.AutoComplete = 1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.CacheSize = 200;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.CallbackPrefix = 'http://localhost:49831/Default.aspx?Cart_ComboBox2_Callback=yes';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ClientEvents = null;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ClientTemplates = [];
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ControlId = 'ComboBox2';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.CollapseSlide = 2;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.CollapseDuration = 200;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.CssClass = 'comboBox';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropDownHeight = 0;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropDownPageSize = 10;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropDownResizingMode = 'Off';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropDownResizingStyle = 'Live';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropDownWidth = 0;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropActiveImageUrl = 'images/drop_hover.gif';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropImageUrl = 'images/drop.gif';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.DropHoverImageUrl = 'images/drop_hover.gif';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.Enabled = 1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.EnableViewState = 1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ExpandDirection = 0;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ExpandDuration = 200;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ExpandSlide = 2;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.FilterCacheSize = 10;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.FocusedCssClass = 'comboBoxHover';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.HoverCssClass = 'comboBoxHover';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ItemCount = 16;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ItemCssClass = 'comboItem';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.ItemHoverCssClass = 'comboItemHover';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.LoadingText = 'LoadingComponentArt控件分析之ComboBox(1)_sed_26';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.KeyboardEnabled = 1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.RunningMode = 0;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.SelectedIndex = -1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.SelectedItemCssClass = 'comboItemHover';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.TextBoxCssClass = 'comboTextBox';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.TextBoxEnabled = 1;
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.TextBoxFocusedCssClass = 'comboTextBox';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.TextBoxHoverCssClass = 'comboBoxHover';
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.InitKeyboard();
ComponentArt控件分析之ComboBox(1)_css_27
ComponentArt控件分析之ComboBox(1)_css_27ComboBox2.Initialize();
ComponentArt控件分析之ComboBox(1)_javascript_78}
ComponentArt控件分析之ComboBox(1)_css_02ComponentArt_Init_ComboBox2();
ComponentArt控件分析之ComboBox(1)_css_02//]]>
ComponentArt控件分析之ComboBox(1)_css_02</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就可以了.
看下代码

ComponentArt控件分析之ComboBox(1)_css_02<div style="position:absolute;top:0px;left:0px;visibility:hidden;"><img src="images/drop_hover.gif" width="0" height="0" alt="" />
ComponentArt控件分析之ComboBox(1)_css_02<img src="images/drop.gif" width="0" height="0" alt="" />
ComponentArt控件分析之ComboBox(1)_css_02<img src="images/drop_hover.gif" width="0" height="0" alt="" />
ComponentArt控件分析之ComboBox(1)_css_02</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);"   更改样式


先到这里,下次继续