我正在阅读复合控件上的一些MSDN示例代码,并发现有一件事我不明白。使用代码here我在项目中创建了LabelTextBox控件并将其添加到页面中。如果我在控件的文本框中输入新值,则当我回发到服务器时,按钮单击事件具有旧值。如果我允许页面继续处理页面,则完成使用新值重新加载。这是一个糟糕的例子还是我错过了什么?在按钮事件触发之前,是否应该将更改的值加载到控件中?
复合控制代码:
public class LabelTextBox : WebControl, INamingContainer
{
public string Text
{
get
{
object o = ViewState["Text"];
if (o == null)
return String.Empty;
return (string)o;
}
set { ViewState["Text"] = value; }
}
public string Title
{
get
{
object o = ViewState["Title"];
if (o == null)
return String.Empty;
return (string)o;
}
set { ViewState["Title"] = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
CreateControlHierarchy();
ClearChildViewState();
}
protected virtual void CreateControlHierarchy()
{
TextBox t = new TextBox();
Label l = new Label();
t.Text = Text;
l.Text = Title;
Controls.Add(l);
Controls.Add(t);
}
}
我尝试以编程方式和编程方式创建控件,但结果没有变化。程序创建代码:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Form.Controls.Add(new LiteralControl("<br /><br />"));
TextBox tb = new TextBox();
tb.Text = "before";
Form.Controls.Add(tb);
Form.Controls.Add(new LiteralControl("<br /><br />"));
LabelTextBox ltb = new LabelTextBox();
ltb.Title = "title";
ltb.Text = "before";
Form.Controls.Add(ltb);
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach( var c in Form.Controls)
{
var control = c as TextBox;
if (control != null)
{
System.Diagnostics.Debug.WriteLine(String.Format("TextBox: {0}", control.Text));
}
else
{
var control2 = c as LabelTextBox;
if (control2 != null)
{
System.Diagnostics.Debug.WriteLine(String.Format("LabelTextBox: {0}", control2.Text));
}
}
}
}
}
答案 0 :(得分:2)
我认为您的第一种方法的问题是您将值保留在父视图状态中,但从不从子视图中读取值。尝试类似:
public class LabelTextBox : WebControl, INamingContainer
{
private Label _Label = new Label() { ID="uxLbl" };
private TextBox _TextBox = new TextBox() { ID="uxTb" };
public string Text
{
get { return _TextBox.Text; }
set { _TextBox.Text = value; }
}
public string Title
{
get { return _Label.Text; }
set { _Label.Text = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
CreateControlHierarchy();
}
protected virtual void CreateControlHierarchy()
{
Controls.Add(_Label);
Controls.Add(_TextBox);
}
}