例如,对TextBox txt,可以:
txt.Attributes.Add("onclick", "fcn0();");
那么,在web页面上click它的时候,就会调用fcn0这个javascript函数。
1.1、例外的情况是,对于IDE无法辨认的属性的解析。
比如对一个RadioButton rbt,IDE不能辨认onclick这个属性,那么,类似上面的语句,
rbt.Attributes.Add("onclick", "fcn1(this);");
在.net framework 1.1中,将解析成
...
而在在.net framework 1.0中,将解析成
...
注意到,fcn1中,参数this对应的对象就不同了。这是一个细微的差别。
2、而对于HTML control,需要多做一点事情。
在设计aspx页面的时候,从工具栏拖一个web form control,比如说,TextBox到页面,会发生两件事:
一、aspx页面多一句
二、code behind多一句
protected System.Web.UI.WebControls.TextBox TextBox1;
如果是html control,那么,第一句中,runat="server"不会出现,而第二局不会被自动添加。
因此,如果要访问html control,需要
一、aspx页面的语句中添加runat="server"属性,成为
二、code behind中显示的声明
protected System.Web.UI.HtmlControls.HtmlInputText htxt;
注意到第一句的id和第二句的变量名是相同的。
2.1、注意到,前面System.Web.UI.WebControls.TextBox对应的html control是System.Web.UI.HtmlControls.HtmlInputText,对应的html的tag是,
相应的,html的tag
对应的html control是public System.Web.UI.HtmlControls.HtmlGenericControl myBody;
2.2、有一点例外的是html的
内容很简单,定义了一个javascript函数fcn1,放了一个Button Button1和一个autopostback的Dropdownlist DropDownList1,运行它,可以看到:点击Button1,会先执行fcn1然后postback,而选择DropDownList1的不同选项,将只会postback,而不会触发fcn1。
微软autopostback=true的webcontrol实现postback,原理是这样的:
一、如果此aspx页面有autopostback=true的webcontrol,那么会写下面一段javascript语句定义一个叫__doPostBack的javascript函数。
二、例如是上面的dropdownlist,将会render成:
这样,通过javscript调用theform.submit();来submit form,postback,但是,theform.submit将不会触发form的onsubmit事件!
这是微软的一个bug。
解决的方法可以看这里:http://www.devhawk.net/art_submitfirefixup.ashx,这里提供了一个dll及源代码,使用的时候,在project的reference里加入这个dll,然后在web.config中加上一段
就可以了。
3、一个应用。
常常听到抱怨,说如果在Browser端用javascript改动了某个
这种情况可能出现在“级联”的DropDownList中,比如第一个DropDownList是省份,第二个是城市;也可能出现在,从第一个DropDownList选择某些项加入到第二个DropDownList中。
对此使用以上的技术,我做了一个这样的解决方案(类似于ViewState的方法):
一、我定义了一个长宽都是0的TextBox txtWrap,并把所有我想处理的DropDownList都加上AthosOsw="True" 这样的属性,准备处理。
二、参照上面2.2的内容,我加入了SubmitFireFixupModule,来保证触发form的onsubmit事件。
三、form的onsubmit事件将执行javascript函数fcnAthosOnSubmitWrap,它将遍历AthosOsw属性为True的DropDownList,记下数据,最后合并起来放到txtWrap里,其实这就是一个序列化的过程。代码如下:
function fcnAthosOnSubmitWrap()
{
txtWrap = document.all["txtWrap"];
var i;
var strWrap = '';
for(i=0;i
ctrl = document.all[i];
if(ctrl.tagName.toUpperCase() == 'SELECT' && typeof(ctrl.AthosOsw) != 'undefined' )
{
if(ctrl.AthosOsw.toUpperCase() == 'TRUE')
{
strWrap += fcnAthosWrapSelect(ctrl) + '&&&';
}
}
}
if(strWrap.length>3)
txtWrap.value = strWrap.substring(0, strWrap.length-3);
};
//AthosOsw
function fcnAthosWrapSelect(ctrlSelect)
{
var i;
var strWrapSelect = ctrlSelect.id + '&' + ctrlSelect.tagName;
var strValue='';
var strText='';
for(i=0; i
strValue = ctrlSelect.options[i].value;
strText = ctrlSelect.options[i].text;
strWrapSelect += '&&' + i + '&' + strValue.replace(/&/g, '%26') + '&' + strText.replace(/&/g, '%26');
};
return strWrapSelect;
};
四、form的Page_Load中调用clsCommon.UnwrapControl(this, txtWrap.Text);来反序列化。clsCommon是我的工具类,UnwrapControl方法代码如下:
static public void UnwrapControl(System.Web.UI.Page pgUnwrap, String strUnwrap)
{
Regex r3 = new Regex("(&&&)"); // Split on hyphens.
Regex r2 = new Regex("(&&)"); // Split on hyphens.
Regex r1 = new Regex("(&)"); // Split on hyphens.
String[] sa3, sa2, sa1;
String s3, s2, s1;
int i3, i2, i1;
String strId, strTagName;
System.Web.UI.Control ctrlUnwrap;
DropDownList ddlUnwrap;
ListItem liAdd;
s3 = strUnwrap;
sa3 = r3.Split(s3);
for(i3=0;i3<(sa3.Length+1)/2;i3++)
{
s2 = sa3[i3*2];
if(s2.Length>0)
{
sa2 = r2.Split(s2);
if(sa2.Length>1)
{
s1 = sa2[0];
sa1 = r1.Split(s1);
if(sa1.Length==3)
{
strId = sa1[0];
strTagName = sa1[2];
ctrlUnwrap = pgUnwrap.FindControl(strId);
if(ctrlUnwrap !=null)
{
if(strTagName == "SELECT")
{
ddlUnwrap = (DropDownList)ctrlUnwrap;
ddlUnwrap.Items.Clear();
for(i2=1; i2 < (sa2.Length+1)/2;i2++)
{
s1 = sa2[i2*2];
sa1 = r1.Split(s1);
liAdd = new System.Web.UI.WebControls.ListItem(sa1[4],sa1[2]);
ddlUnwrap.Items.Add(liAdd);
}
}
}
}
}
}
}
}