Reputation: 1190
I need to access the controls created by CreateChildControls() from another class, so that when I choose the file I have the path on a string to refer to.
I have tried the solutions in Accessing controls created dynamically (c#) and Problem in accessing dynamically created controls But with no joy thanks
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);
}
From another class I should be able to access the textbox
protected void Button1_Click(object sender, EventArgs e)
{
AssetPicker asspi = new AssetPicker();
string aaa = asspi.txtUrl.Text;
}
Upvotes: 3
Views: 2037
Reputation: 124756
I had to make the controls public to be accessible from another class. but it retuns null reference error. I have updated the initial post
If you expose your child controls publicly, you need to call EnsureChildControls
in the getter for each publicly-exposed child control. This will force CreateChildControls
to be executed, and hence your control tree to be built, ensuring the caller does not get a null reference.
E.g.:
public Button MyChildButton
{
get
{
EnsureChildControls();
return _myChildButton;
}
}
private Button _myChildButton;
...
protected override void CreateChildControls()
{
...
_myChildButton = new Button();
...
}
Note that in order to do this, you need to expose your child controls as properties, not fields. I.e. in your sample code, you need to replace:
public TextBox txtUrl;
by:
public TextBox TxtUrl
{
get
{
EnsureChildControls();
return txtUrl;
}
}
private TextBox txtUrl;
You should also inherit from CompositeControl
, which does something similar for the Controls
property:
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
If for some reason you are not inheriting from CompositeControl
, then you'll need to add this Controls override to your class.
Incidentally, exposing child controls might be giving too much information to your callers, who probably shouldn't be concerned with such implementation details. Instead you could expose only the relevant properties of your child controls. For example, instead of exposing a child TextBox TxtUrl
, you could expose a string property Url
thus:
public string Url
{
get
{
EnsureChildControls();
return txtUrl.Text;
}
set
{
EnsureChildControls();
txtUrl.Text = value;
}
}
Upvotes: 5
Reputation: 8362
At the end, what .NET does when you add a static control to a page, it will hold a reference as of the control as a field (they usually go to the .designer file). So, just put the controls as fields in the same fashion:
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);
}
Upvotes: 0