我需要从另一个类访问CreateChildControls()创建的控件,这样当我选择文件时,我会在字符串上引用路径。
我在Accessing controls created dynamically (c#)和Problem in accessing dynamically created controls中尝试过这些解决方案但是没有快乐,谢谢
publicTextBox txtUrl;
protected override void CreateChildControls()
{
Label lblUrl = new Label();
lblUrl.ID = "lblUrl";
lblUrl.Text = "Url: ";
Controls.Add(lblUrl);
TextBox txtUrl = new TextBox();
txtUrl.ID = "txtUrl";
Controls.Add(txtUrl);
AssetUrlSelector picker = new AssetUrlSelector();
picker.ID = "ausUrl";
picker.DefaultOpenLocationUrl = OpenUrl;
picker.AssetUrlClientID = txtUrl.ClientID;
picker.AssetUrlTextBoxVisible = false;
Controls.Add(picker);
Control control = Page.LoadControl(_ascxPath);
Controls.Add(control);
}
从另一个班级我应该可以访问文本框
protected void Button1_Click(object sender, EventArgs e)
{
AssetPicker asspi = new AssetPicker();
string aaa = asspi.txtUrl.Text;
}
答案 0 :(得分:5)
我必须让控件公开才能从另一个类访问。但它重新调整了空引用错误。我已更新了最初的帖子
如果您公开公开您的子控件,则需要在每个公开公开的子控件的getter中调用EnsureChildControls
。这将强制执行CreateChildControls
,从而构建控件树,确保调用者不会获得空引用。
E.g:
public Button MyChildButton
{
get
{
EnsureChildControls();
return _myChildButton;
}
}
private Button _myChildButton;
...
protected override void CreateChildControls()
{
...
_myChildButton = new Button();
...
}
请注意,为了执行此操作,您需要将子控件公开为属性,而不是字段。即在示例代码中,您需要替换:
public TextBox txtUrl;
由:
public TextBox TxtUrl
{
get
{
EnsureChildControls();
return txtUrl;
}
}
private TextBox txtUrl;
您还应该继承CompositeControl
,它会对Controls
属性执行类似操作:
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
如果由于某种原因您没有继承CompositeControl
,那么您需要将此控件覆盖添加到您的班级。
顺便说一句,暴露子控件可能会给您的调用者提供太多信息,他们可能不应该关注这些实现细节。相反,您只能公开子控件的相关属性。例如,您可以公开字符串属性TxtUrl
,而不是公开子TextBox Url
:
public string Url
{
get
{
EnsureChildControls();
return txtUrl.Text;
}
set
{
EnsureChildControls();
txtUrl.Text = value;
}
}
答案 1 :(得分:0)
最后,当您向页面添加静态控件时,.NET会执行什么操作,它将控件的引用作为字段保存(它们通常会转到.designer文件)。所以,只需将控件作为字段以相同的方式放置:
private Label lblUrl;
private TextBox txtUrl;
private AssetUrlSelector picker;
private Control control;
protected override void CreateChildControls()
{
lblUrl = new Label();
lblUrl.ID = "lblUrl";
lblUrl.Text = "Url: ";
Controls.Add(lblUrl);
txtUrl = new TextBox();
txtUrl.ID = "txtUrl";
Controls.Add(txtUrl);
picker = new AssetUrlSelector();
picker.ID = "ausUrl";
picker.DefaultOpenLocationUrl = OpenUrl;
picker.AssetUrlClientID = txtUrl.ClientID;
picker.AssetUrlTextBoxVisible = false;
Controls.Add(picker);
control = Page.LoadControl(_ascxPath);
Controls.Add(control);
}