先还是看看这篇文章
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcondevelopingcompositecontrols.asp
开发复合控件跟开发用户控件有一些不同。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcompositecontrolvsusercontrol.asp
最近遇到一个问题:
在编辑web页面希望出现的是输入框,而在显示状态的时候,希望出现的Label来显示文字。
自己继承了一个Label完成这个要求
中间遇到了一些问题:
1 如果是开发复合控件,必须完成接口:System.Web.UI.INamingContainer interface
而这个接口并没有方法
. When a control implements INamingContainer, the ASP.NET page framework creates a new naming scope under that control, thus ensuring that the child controls have unique names in the hierarchical tree of controls
只是asp。net框架会创建新的命名范围,〔晕,什么意思?〕
根据我的理解,意思是它会为每个子控件创建唯一的ID来区别;
如果父控件的UniqueID是MyEditLabel1,则子控件的UniqueID是MyEditLabel1:_ctl0
ctl是control的缩写,今天才想明白。
2 在子控件未加载到父控件之前,子控件的UniqueID是空的,
//myText.UniqueID 为null
this.Controls.Clear();
this.Controls.Add(myText);
//此时myText.UniqueID 不为null
3 子控件之间传递值的方式,可以有两种,
一种是通过post后,viewstat来读取
而另一种则是;通过post后Request类的方法读取
myLabel.Text = System.Web.HttpContext.Current.Request[myLabel.UniqueID];
update 12:42
4 如果是重写了GetDesignTimeHtml方法,
需要重新启动vs.net,才能在设计时显示出更改后的方法。
string html ="";
if(d.Width!=Unit.Empty)
html = String.Format("<input type=text style="{0}px" >",d.Width.Value);
else
html = String.Format("<input type=text style="{0}px" >",80);
// html = "<input type=text style="64px" >";
return html;
5. 控件创建的顺序
=============================
CreateChildControls()
……》
页面的
MyEditLabel2.EditEnable = false;
……》
控件的属性被更改
=============================
根据这个顺序,
如果属性被更改后要起作用,实际上在set之后还需要加载一次
{
get
{
EnsureChildControls();
if(myLabel!=null)
text = myLabel.Text;
if(myText!=null)
text = myText.Text;
return text;
}
set
{
text = value;
CreateChildControls();//重新调用一次
}
}