根据前面对复合控件的开发的简单研究,综合前面所学的知识,实现了一个简单的ComboBox的控件的练习,程序的设计思路如下,利用一个input标签、一个Img标签、和前台的window.createPopup()对象生成一个简单的ComboBox控件,将描述此控件的样式文件,和执行的前台的js文件放如一个固定的文件夹my controls中以便用户使用。本示例仅仅实现了简单的combox控件的功能,还有很多地方值得进一步修改。
.具体的实现过程如下.
第一步:建立自定义控件的工程命名为myComboBoxs,至于具体的创建过程在前面已经叙述过了在此不在叙述。
第二步:建立测试工程TestCombobox
第三步:建立描述控件样式的样式表文件和执行前台功能的js文件.
ComboBox具体实现代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: TagPrefix("my.ComBox", "ylj")]
namespace my.ComBox

...{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ComBox runat=server></{0}:ComBox>")]
public class ComBox : WebControl,ICallbackEventHandler

...{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public override string ID

...{
get

...{
return base.ID;
}
set

...{
base.ID = value;
}
}

/**////<summary>
/// 获取用户选择内容
///</summary>
public string Text

...{
get

...{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}

set

...{
ViewState["Text"] = value;
}
}

/**//// <summary>
/// 是否允许用户输入值,为使控件既可以同过选择值,又可以通过用户输入设置此属性。
/// </summary>
public bool AllowWrite

...{
get

...{
if (ViewState["AllowWrite"] == null)

...{
return true;
}
else

...{
return (bool)ViewState["AllowWrite"];
}
}
set

...{
ViewState["AllowWrite"] = value;
}
}

/**//// <summary>
/// 生成ComBoxItem的值
/// </summary>
public string ItemsValue

...{
get

...{
if (ViewState["ItemValue"] == null)

...{
return "";
}
else

...{
return ViewState["ItemValue"].ToString();
}
}
set

...{
ViewState["ItemValue"] = value;
}
}

/**//// <summary>
/// 设置控件的宽度
/// </summary>
public override Unit Width

...{
get

...{
if(ViewState["Width"]==null)

...{
return base.Width;
}
else

...{
return (Unit)ViewState["Width"];
}
}
set

...{
ViewState["Width"] = value;
}
}

/**//// <summary>
/// 样式表和js文件的所在路径
/// </summary>
public string ControlsURL

...{
get

...{
if (ViewState["ControlsURL"] == null)

...{
return "My Controls/";
}
else

...{
return ViewState["ControlsURL"].ToString();
}
}
set

...{
ViewState["ControlsURL"] = value;
}
}
public string CssStyle

...{
get

...{
if (ViewState["CssStyle"] == null)

...{
return "Default";
}
else

...{
return ViewState["CssStyle"].ToString();
}
}
set

...{
ViewState["CssStyle"] = value;
}
}
public event EventHandler ComBox_Request;
protected virtual void OnComBox_Request(object sender,EventArgs e)

...{
if(ComBox_Request!=null)

...{
ComBox_Request(this, e);
}
}
public string GetCallbackResult()

...{
return ItemsValue;
}
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)

...{
OnComBox_Request(this, EventArgs.Empty);
}
protected override void OnPreRender(EventArgs e)

...{
ClientScriptManager curClientScriptManger = Page.ClientScript;
curClientScriptManger.RegisterClientScriptInclude(this.GetType(), "0", ControlsURL.ToString() + "JS/CreateCombox.js");
base.OnPreRender(e);
}
protected override void RenderContents(HtmlTextWriter output)

...{
output.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
output.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
output.AddAttribute(HtmlTextWriterAttribute.Href, ControlsURL + "Css/ComBox/ComBox.css");
output.RenderBeginTag(HtmlTextWriterTag.Link);
output.RenderEndTag();
output.AddAttribute(HtmlTextWriterAttribute.Type, "Text");
output.AddAttribute(HtmlTextWriterAttribute.Value, "");
output.AddAttribute(HtmlTextWriterAttribute.Class, "Combox_"+CssStyle.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Id, "Textbox_" + ID);
output.AddAttribute(HtmlTextWriterAttribute.Onclick, Page.ClientScript.GetCallbackEventReference(this, null, "CreatComboBox", "Textbox_" + ID) + ";return false;");
if ((bool)AllowWrite == true)

...{
output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
}
output.RenderBeginTag(HtmlTextWriterTag.Input);
output.RenderEndTag();
output.AddAttribute(HtmlTextWriterAttribute.Src, ControlsURL.ToString() + "Css/ComBox/Img/DropArrow.gif");
output.AddAttribute(HtmlTextWriterAttribute.Class, "BtnImg_"+CssStyle.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Onclick, Page.ClientScript.GetCallbackEventReference(this, null, "CreatComboBox", "Textbox_" + ID) + ";return false;"); ;
output.RenderBeginTag(HtmlTextWriterTag.Img);
output.RenderEndTag();
}
}
}

具体生成控件并实现功能前台的js脚本代码如下:

var oPopup=window.createPopup();
var popt=false;
var ShowPopupFlag=false;


function CreatComboBox(str,obj)

...{
var Arr=str.split(",");
var CreateCheckBox = '';
var TextBox=obj.id;
var PopTop = getIET(obj)+21;
var PopLeft=getIEL(obj);
for(var i=0;i<Arr.length;i++)

...{
CreateCheckBox+="<div id="div"+ i +"" class="ComboBoxItem_Mac" onmouseover='this.className="ComboBoxItemHover_Mac"' onmouseout='this.className="ComboBoxItem_Mac"'><input name=checkbox type=checkbox id=checkbox"+i+" value="+Arr[i]+" onclick=GetValeu(this) /><span style="line-height:18px;left:15px; width:78%;" id="pan"+i+"" onclick=ChangeChildStatus(this.id)>"+Arr[i]+"</span></div>"
}
var styleStr='<style type=text/css>body{background-image: url(My Controls/Css/ComBox/Img/dropdownBg.gif);border: 1px solid #C3C3C3;border-top: none; scrollbar-face-color: #F8F6F2;scrollbar-highlight-color: #ffffff;scrollbar-shadow-color:#E9E9E9;scrollbar-3dlight-color:#DBDBDB;scrollbar-arrow-color:#787878;scrollbar-track-color: #F5F5F5;scrollbar-darkshadow-color: #AEAEAE; }.ComboBoxItem_Mac{font-family:Arial;font-size:11px;color:#333333;padding: 0px;text-decoration:none;text-align:left;}.ComboBoxItemHover_Mac{font-family: Arial;font-size:11px; color:white;text-decoration: none;background-color: #777777;cursor: hand;padding: 0px;text-align: left;}</style>';
var HtmlStr='<html><head><title></title><script>function ChangeChildStatus(ParentId){var objId="checkbox"+ParentId.substring(3,ParentId.length);var obj=document.getElementById(objId);if(obj.checked){obj.checked=false;}else{obj.checked=true;}GetValeu(obj); }function GetValeu(obj){var Result=parent.document.getElementById("'+TextBox+'").value;if(obj.checked){Result=Result + obj.value +","}else{var CheckValue=Result.indexOf(obj.value);Result=Result.substring(0,CheckValue)+Result.substring(CheckValue+1+obj.value.length,Result.length) }parent.document.getElementById("'+TextBox+'").value=Result;parent.document.getElementById("'+TextBox+'").title=Result;}function Status(obj){var NewArr=obj.split(",");var CheckBoxList=document.getElementsByName("checkbox");for(var i=0;i<NewArr.length;i++){for(var j=0;j<CheckBoxList.length;j++){if(CheckBoxList[j].value==NewArr[i]){CheckBoxList[j].checked=true;}}}}</script>'+styleStr+'</head><body leftmargin=0 topmargin=0 >'+CreateCheckBox+'<script>Status(parent.document.getElementById("'+TextBox+'").value);document.oncontextmenu=function(){return false};document.onselectstart=function(){return false}</script></body>'
oPopup.document.body.innerHTML = "";
var oPopBody = oPopup.document.body;
oPopup.show(PopLeft,PopTop, 122, 150, document.body);
oPopup.document.write(HtmlStr);
}

function getIET(e)...{
var t=e.offsetTop;

while(e=e.offsetParent)...{
t+=e.offsetTop;
}
return t;
}


function getIEL(e)...{
var l=e.offsetLeft;

while(e=e.offsetParent)...{
l+=e.offsetLeft;
}
return l;}

前台的样式文件定义如下:
.Combox_Default

{...}{
background-image: url(Img/bg.gif);
background-repeat: repeat-x;
vertical-align: middle;
font-family: Arial, Verdana;
border: 0px;
margin-right: 0px;
border-left: 1px solid #B3B3B3;
font-size: 12px;
color: black;
padding-top: 0px;
padding-left: 3px;
height: 21px;
width:100px
}
.BtnImg_Default

{...}{
vertical-align: middle;
}
本示例仅仅简单的实现了ComboBox的部分功能,本人希望它还能支持主题皮肤的功能,因此将继续研究下去。