I have this code:
Control ctrl = Page.LoadControl("~/UserControls/ReportControl.ascx");
IReport rpt = (IReport)ctrl;
rpt.LoadData();
Panel.Controls.Add(ctrl);
So far everything is working as expected.
Now I need on Button click postback event to get the loaded control and cast to the interface to use a method, and tried this:
if (Panel.Controls.Count > 0) {
Control ctrl = Panel.Controls[0] as Control;
IReport rpt = ctrl as IReport;
string result = rpt.AMethodToInvoke();
}
This cast cannot happen and the control I get from the panel is a LiteralContol.
Any ideas? Thank you.
Have you got any other controls in your panel?
Maybe give your control an ID so
Control ctrl = Page.LoadControl("~/UserControls/ReportControl.ascx");
ctrl.ID = "UniqueID";
IReport rpt = (IReport)ctrl;
rpt.LoadData();
Panel.Controls.Add(ctrl);
And then user FindControl on the panel
Control ctrl = Panel.FindControl("UniqueID");
Also as you are adding the controls dynamically you need to make sure you are re-adding them on postback otherwise when you run the FindControl() it will return null.
Related
in asp.net TextBox will create pressure to button1's. Button2 to the pressure inside the TextBox data consisting of label1 my yazdırıca. I tried to do it like this gives an error.
Object reference not set to an instance of an object.
button1_click{
TextBox txt = new TextBox();
txt.ID = "a";
txt.EnableViewState = true;
Panel1.Controls.Add(txt);
}
Button2_click{
TextBox deneme= Panel1.FindControl("a") as TextBox;
Label1.Text = deneme.Text;
}
After you create your control, on the first click, the control shown on the page and exist.
On the second click the page is not know any more about that text control because you did not save that information somewhere and because only you know that some time in the past you create it.
So on this code you have:
Button2_click{
TextBox deneme= Panel1.FindControl("a") as TextBox;
// here the deneme is null ! and you get the exception !
// the deneme is not exist on the second click, not saved anywhere
Label1.Text = deneme.Text;
}
The solution is to keep on viewstate what control you create and how, and re-create them on PageInit. Alternative you can redesign your page and think a different approach to that, eg you can have the TextControl's all ready on page hidden, and just open them.
Button2_click{
TextBox txt = (TextBox)Panel1.FindControl("a");
Label Label1 = new Label();
Label1.Text=txt.Texxt;
}
I am building many textboxes programmatically in my ASP.NET page, after I've clicked a button, I would like to process those values, is there any possibility to retrieve them from their ID in ViewState ?
Here is my code :
Reference of the table in the aspx :
<asp:Table ID="Distances" runat="server" ViewStateMode="Inherit"></asp:Table>
Then in code behind after creating all the rows and cells, I add a textbox into some of them :
Distances.Rows[j].Cells[i].Controls.Add(CreateTB(distance.ToString(), (i + j * rows).ToString(), false));
protected TextBox CreateTB(string text, string id, bool ebanled = true)
{
TextBox tb = new TextBox() { Text = text, ID = id, Enabled = ebanled};
tb.TextChanged += new EventHandler(OnTBChanged);
return tb;
}
ViewState is enabled by default, so it should already work that the Text property is persisted across postbacks.
So you could for example use FindControl("TextBoxID") or enumerate them to get the refernce to the TextBox (assuming that they are added to a container-control like Panel):
foreach(TextBox txt in MyPanel.Controls.OfType<TextBox>())
{
String text = txt.Text;
}
or
TextBox txt = (TextBox)MyPanel.FindControl("TextBox1")
String text = txt.Text;
I assume you're not recreating those TextBoxes on postbacks. Therefore you need to use the same ID as before and recreate them in Page_Load at the latest stage in page's life-cycle. So you can create them in an event, but you cannot recreate them there.
You should show your code where you create them dynamically, then i could be more specific.
TRULY UNDERSTANDING DYNAMIC CONTROLS
I have a UserControl. I dynamically create some controls (Columns for SPGridView. Grid control was added in markup, ObjectDataSource, Button and Label) in CreateChildControl method and add them to Controls collection. Two of these controls are added well (Button and Label) in postback, but one of them (MenuTemplate) raise the exception with such content:
"Failed to load viewstate. The control tree into which viewstate is
being loaded must match the control tree that was used to save
viewstate during the previous request. For example, when adding
controls dynamically, the controls added during a post-back must match
the type and position of the controls added during the initial
request. "
When I move my code to OnInit method all controls are added successfully. So, I have a question: Could someone explain me why some controls are added to Controls collection successfully and others are failed in CreateChildControls in postback? I have read about ViewState here. Probably I didn't understand some moments.
Look at me code:
protected override void CreateChildControls()
{
Label l = new Label();
l.ID = "labelTest";
l.Text = "Hello test!";
Button b = new Button();
b.Text = "Press test";
b.ID = "buttonTest";
b.Click += b_Click;
Controls.Add(l);
Controls.Add(b);
ObjectDataSource gridDataSource = new ObjectDataSource();
gridDataSource.ID = "gridDataSource";
gridDataSource.SelectMethod = "GetDataSource";
gridDataSource.TypeName = this.GetType().AssemblyQualifiedName;
Controls.Add(gridDataSource);
SPMenuField colMenu = new SPMenuField();
colMenu.HeaderText = "Test";
colMenu.TextFields = "Test";
colMenu.MenuTemplateId = "ListMenu";
// it is my SPGridView that added in markup
customGridView.Columns.Add(colMenu);
MenuTemplate titleListMenu = new MenuTemplate();
titleListMenu.ID = "ListMenu";
// The exception occurs here
Controls.Add(titleListMenu);
base.CreateChildControls();
}
I think, you can only add items into a template in Page_Load or other events(ie, after Page_Init) so that it will be retained in postback, not the template itself.. Templates are need to be created before or at Page_Init stage, otherwise it may not load the controls into that templates from viewstate or may result in error.
There are test.aspx page and test.ascx web user control.
I have a button in test.aspx = btn_test and above code in my button is :
Dim ct As Control = Page.LoadControl("test.ascx")
Panel1.Controls.Add(ct)
There is a dropdownlist with value 1 to 10 in test.aspx and there is label_test in test.ascx
I need some code when test.ascx loading, get dropdownlist.selectedvalue and show it in label_test.
Please help me !
There are a number of ways to implement this. One you could try would be to cast the test.ascx web control being loaded like so (replace TestControl with the class name for the control):
Dim ct As TestControl = CType(Page.LoadControl("test.ascx"), TestControl)
And then create a public property in the control which you would use to set the value from the DropDownList.
Dim ct As TestControl = CType(Page.LoadControl("test.ascx"), TestControl)
ct.DropDownListValue = DropDownList.SelectedItem.Value
Panel1.Controls.Add(ct)
This property would then be used to set the labels value (either directly using the set accessor or via a method within the test.ascx control).
x.Parameters.AddWithValue("#areasexpertise1", FindControl("AreasExpertise1"))
It should find AreasExpertise1 and make a parameter, but does that get the selectedvalue too?
The code you posted will find the control and will return it as a Control object.
You need to cast it to whatever control it is (DropDownList or RadioButtonList, or whatever it is you are using), and then call the SelectedValue property on it in order to do so:
var ctrl = FindControl("AreasExpertise1") as DropDownList;
if (ctrl != null)
x.Parameters.AddWithValue("#areasexpertise1", ctrl.SelectedValue)