I'm working on a report management system. Each report has its own parameters. Parameter names and saved values are kept in the database.
When the user selects a report from a GridView, the parameter names and values are dynamically created like so. Note that during development, I'm just adding a Label for the Parameter Name and a Textbox for the Parameter Value. In its final version, there will be several different types of Parameter Value controls (e.g., DropDownList, ListBox, Calendar).
DataSet ds = dal.GetSavedParameters(reportID);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
DataRow dr = ds.Tables[0].Rows[i];
Label lbl = new Label();
Literal ltl = new Literal();
ltl.ID = "ltl" + i.ToString();
lbl.ID = "lbl" + i.ToString();
lbl.Text = dr["ParameterName"].ToString();
TextBox txt = new TextBox();
txt.ID = "parm" + i.ToString(); // any control will have the ID "parm" + i, not just TextBoxes
txt.Text = dr["ParameterValue"].ToString();
pnlParameters.Controls.Add(lbl); // an asp:Panel
pnlParameters.Controls.Add(txt);
pnlParameters.Controls.Add(ltl); // to add a line break between parameter name/value pairs
}
This will create dynamic controls named "lbl0", "ltl0", "parm0", "lbl1", "ltl1", "parm1", etc.
Now when it's time to Update the Parameters (i.e., the user has decided to store different values for this report). I can't find the Labels or Textboxes. I've used some of the following:
DataSet ds = dal.GetSavedParameters(reportID); // get the stored values for update later
DataTable dt = ds.Tables[0];
foreach(DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
string labelName = "lbl" + i.ToString();
string valueName = "parm" + i.ToString();
Label lblName = new Label();
lblName = (Label)pnlParameters.FindControl(labelName);
...
}
lblName keeps coming back "null". By the way, if I use the name of a "real" label (e.g., "lblTest"), this word just fine.
I've also tried a helper method:
private static Control Find(Control C, string ControlName)
{
if (C.ID == ControlName) return C;
foreach(Control c in C.Controls)
{
Control cntrl = Find(c, ControlName);
if (cntrl != null) return c;
}
return null
}
This is called as:
Label lblName = (Label)Find(pnlParameters, labelName);
Label still comes back null.
Any ideas?
TIA,
Michell
Loading
Suthish NairPosted Mar 10, 2011, 1:09 PM
The Panel.Control.Count is always 1.
Michell TurleyPosted Mar 9, 2011, 11:10 AM
I've located a job that works for WinForm; I going to try to modify it to work for WebForms.
Thanks for all your help,
Michell
Raja KrishnamurthyPosted Mar 8, 2011, 10:08 PM
Assume that the user clicks on Ok (which loads true in the hidden field) then you are trying to
int scenarioID = Convert.ToInt32(grdSavedScenarios.SelectedDataKey.Value);
UpdateParameters(scenarioID);
LoadScenario(scenarioID);
Here UpdateParameters (which essentially gets all the values from the dynamically generated code) is called before you actually load the scenario(where you dynamically load the controls)
HTH.
Happy Programming!!!
Regards,
Raja
PS. All your other code is perfect as far as I can see and would work fine :-)....Saving data to viewstate is a bad programming practice and a performance hit too.
Michell TurleyPosted Mar 8, 2011, 5:20 PM
protected void btnNewScenarioName_Click(object sender, EventArgs e)
{
// OnClientClick executes a Javascript "confirm", asking the user if he wants to over-write the existing report
// parameter values, which writes the result ("true"/"false") to a
// asp:HiddenField called hdnConfirm
string confirm = hdnConfirm.Value.ToString();
if (confirm == "false") // don't overwrite the existing parameter values. I'll change the name of the report
{
int scenarioID = Convert.ToInt32(grdSavedScenarios.SelectedDataKey.Value);
LoadScenario(scenarioID); // to refresh the Scenario gridview
txtNewScenarioName.Focus(); // this doesn't seem to be working either. I'm assuming it's the postback
} // end if
else
{
int scenarioID = Convert.ToInt32(grdSavedScenarios.SelectedDataKey.Value);
UpdateParameters(scenarioID);
LoadScenario(scenarioID);
} // end else
} // end method btnNewScenarioName_Click
private void LoadScenario(int scenarioID)
{
Parameters dal = new Parameters(); // DAL class
DataSet ds = dal.GetSavedParameters(scenarioID);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
DataRow dr = ds.Tables[0].Rows[i];
Label lbl = new Label();
Literal ltl = new Literal();
TextBox txt = new TextBox();
lbl.ID = "lbl" + i.ToString();
lbl.Text = dr["ParameterName"].ToString();
ltl.ID = "ltl" + i.ToString();
ltl.Text = "
";
txt.ID = "txt" + i.ToString();
txt.Text = dr["ParameterValue"].ToString();
pnlParameters.Controls.Add(lbl);
pnlParameters.Controls.Add(txt);
pnlParameters.Controls.Add(ltl);
} // end for
} // end method LoadScenarios
private void UpdateParameters(int scenarioID)
{
Parameters dal = new Parameters(); // DAL
DataSet ds = dsl.GetSavedParameters(scenarioID);
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
string labelName = "lbl" + i.ToString();
string valueName = "parm" + i.ToString();
Label lblName = (Label)pnlParameters.FindControl(labelName); // Label returns null
TextBox txtValue = (TextBox)pnlParameters.FindControl(valueName); // TextBox returns null
} // end for
} // end foreach
} // end method UpdateParameters
// this is as far as I've gotten. with the controls returning "null", there's no sense
// in trying to get the values from them.
I'm thinking maybe I could create a dynamic method for TextBox_TextChanged. That could stored the appropriate values, together with the associated names into a ViewState control, or into HiddenFields. Only concern there is to ensure that I have enough controls to hang on to everything.
Any other ideas?
Thanks,
Michell
Raja KrishnamurthyPosted Mar 8, 2011, 4:43 PM
Regards,
Raja
Michell TurleyPosted Mar 8, 2011, 4:40 PM
That could be a problem. Can I use ViewState to keep track of the new values the user has entered?
Michell
Raja KrishnamurthyPosted Mar 8, 2011, 4:37 PM
if (!this.IsPostBack)
{
//Load the report parameter data
}
If you had not checked this then on Postback (due to button click) it is going to bring back the data again and load the controls. This could be why the it is returning null when you try to find it.
HTH.
Happy Programming!!!
Regards,
Raja
Michell TurleyPosted Mar 8, 2011, 4:31 PM
Thanks for your input.
This is, in fact triggered by a button_click, and a postback is involved.
Am I missing something there?
Thanks,
Michell
Raja KrishnamurthyPosted Mar 8, 2011, 4:24 PM
HTH.
Happy Programming!!!
Regards,
Raja