第一次遇到这个问题是两年前。
页面上有几个只读的文本框,在保存信息之前,页面发生了回发,可是这几个文本框的值却不见了。当时很困惑,不过由于刚毕业且刚刚接触.Net,并不知道怎样查找出现这个问题的原因。最后只好去掉了ReadOnly属性,并加上onkeydown="return false;"来代替。
这两天又遇到了这种情形。我们用一个简单的页面来模拟这种情形。页面包含一个只读文本框和一个按钮。
<asp:TextBox ID="txtTest" runat="server" ReadOnly="true"></asp:TextBox>
<asp:Button ID="btn" runat="server" Text="Button" />
<script type="text/javascript">
<% if( !IsPostBack){ %>
var txt = document.getElementById('<%=txtTest.ClientID %>');
txt.value = "test";
<%}%>
</script>
文本框只有页面第一次加载才会被赋值。此后如果点击按钮,文本框的值就‘神奇’地失踪了。
为什么呢?
最开始我想难道是只读的文本框值不会被回发。于是写了一个继承自TextBox的控件来验证(本来想用reflector来调试TextBox,无奈过期了):
public class MyTextBox : TextBox
{
protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
return base.LoadPostData(postDataKey, postCollection);
}
}
然而postCollection却是包含了该文本框的值的。
那究竟为何呢?看看下面的代码就明白了(Button的源代码):
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
base.ValidateEvent(postDataKey);
string text = this.Text;
string str2 = postCollection[postDataKey];
if (!this.ReadOnly && !text.Equals(str2, StringComparison.Ordinal))
{
this.Text = str2;
return true;
}
return false;
}
是的,问题就在于!this.ReadOnly ,对于只读的文本框回发后是不会给它赋值的。