根据前面对复合控件的开发的简单研究,综合前面所学的知识,实现了一个简单的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" οnmοuseοver='this.className="ComboBoxItemHover_Mac"' οnmοuseοut='this.className="ComboBoxItem_Mac"'><input name=checkbox type=checkbox id=checkbox"+i+" value="+Arr[i]+" οnclick=GetValeu(this) /><span style="line-height:18px;left:15px; width:78%;" id="pan"+i+"" οnclick=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.οncοntextmenu=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的部分功能,本人希望它还能支持主题皮肤的功能,因此将继续研究下去。