C# .NET - Saving data from a dynamically created Field for DetailsView in C#

Asked By João Silva on 05-Sep-13 01:07 PM
Hi all,

Here is my problem. Based on previous posts I have manage to create dynamically fields on a Detailsview. My problem now is to retrieve the data from those fields after user click on "Save" button.

Here is my code:

In here I add the controls I want:



//Detail objects friendlynames DataTable dtObjectFName = ds.Tables[0]; //Detail objects types
DataTable dtObjectTypes = ds.Tables[1];
for (int i = 0; i < dtObjectFName.Columns.Count; i++)

{

TemplateField tf1 = new TemplateField();

tf1.HeaderTemplate =


new DetailsViewTemplate(DataControlRowType.Header, dtObjectFName.Rows[0][i].ToString(), dtObjectFName.Rows[0][i].ToString(), new Label());

tf1.ItemTemplate =


new DetailsViewTemplate(DataControlRowType.DataRow, dtObjectFName.Columns[i].ColumnName, dtObjectFName.Columns[i].ColumnName, Generic.ReturnControl(dtObjectTypes.Rows[0][i].ToString()));

dvEditDetail.Fields.Add(tf1);

}

Here is my "DetailsViewTemplate" class

System;  

using System.Collections.Generic;

 

using

System.Linq;
 

using

System.Web;
 

using

System.Web.UI;
 

using

System.Web.UI.WebControls;
 

namespace

LISPP.Classes

{



public class DetailsViewTemplate : ITemplate
 

{

private DataControlRowType templateType;
private string columnNameFriendly;
private string columnNameData;
private Control control;
public DetailsViewTemplate(DataControlRowType type, string colNameFr, string colNameDt, Control con)

{

templateType = type;

columnNameFriendly = colNameFr;

columnNameData = colNameDt;

control = con;

}

public void InstantiateIn(System.Web.UI.Control container)

{

switch (templateType)

{

case DataControlRowType.Header:

{

Literal lc = new Literal();

lc.Text = columnNameFriendly;

container.Controls.Add(lc);

break;

}

case DataControlRowType.DataRow:

{

Control field = control;

field.EnableViewState =


true;

field.DataBinding +=


new EventHandler(this.field_DataBinding);

container.Controls.Add(field);

break;

}

}

}

private void field_DataBinding(Object sender, EventArgs e)

{

Control c = (Control)sender;
DetailsView row = (DetailsView)c.NamingContainer;
if (sender.GetType() == typeof(Label))

{

if (row.DataItem != null)

(c


as Label).Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();

(c


as Label).Font.Size = 7;

(c


as Label).Font.Name = "verdana";

(c


as Label).EnableViewState = true;

}



else if (sender.GetType() == typeof(TextBox))

{



if (row.DataItem != null)

(c


as TextBox).Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();

(c


as TextBox).Font.Size = 7;

(c


as TextBox).Font.Name = "verdana";

(c


as TextBox).Attributes.Add("style", "width:100%;");

(c


as TextBox).EnableViewState = true;

}

else if (sender.GetType() == typeof(DropDownList))

{

if (row.DataItem != null)

(c


as DropDownList).SelectedValue = DataBinder.Eval(row.DataItem, columnNameData).ToString();

(c


as DropDownList).Font.Size = 7;

(c


as DropDownList).Font.Name = "verdana";

(c


as DropDownList).EnableViewState = true;

}

else if (sender.GetType() == typeof(CheckBox))

{

if (row.DataItem != null)

(c


as CheckBox).Checked = (bool)DataBinder.Eval(row.DataItem, columnNameData);

(c

as CheckBox).EnableViewState = true;

}

}

}

}

And in here I supposedly retrieve the data from the controls:


protected

void BtnSave_Click(object sender, EventArgs e)

{

try
 

{

if (Page.IsValid)

{

if (ViewState["DataSetDetail"] == null)

{

throw new Exception("No DataSetDetail!");

}

DataSet ds = (DataSet)ViewState["DataSetDetail"]; if (ds == null)

{

throw new Exception("DataSetDetail is empty!");

}


int
itens = dvEditDetail.Fields.Count;
in here there are no itens! int items = dvEditDetail.Rows.Count;
in here there are no itens!
for
(int i = 0; i < items; i++)

{

TemplateField tf = (TemplateField)dvEditDetail.Fields[i]; DetailsViewTemplate dvt = (DetailsViewTemplate)tf.HeaderTemplate;

dvEditDetail.FindControl(


"x"); Parameter p = new Parameter(); //dvEditDetail.Rows[i].Cells[1].Controls[0]  

}

//   ////dvEditDetail.Field   //foreach (DataControlField dcf in dvEditDetail.Fields)   //{   // //dcf.  
// //dvEditDetail.Rows[0].Cells[1].Controls[0]
 
//}
 
//for (int i = 0; i < items; i++)
 
//{
 
// dvEditDetail.Rows[i].Cells[1].Controls[0]

 
//}
 
//string ShopOutGDCId;
 
//if (dvEditDetail.CurrentMode == DetailsViewMode.Insert)
 
//{
 
// ShopOutGDCId = "0";
 


//}
 
//else
 
//{
 
// ShopOutGDCId = ((TextBox)dvEditDetail.FindControl("txtShopOutId")).Text;
 
//}
 
//string ShopCode = ((TextBox)dvEditDetail.FindControl("txtShopCode")).Text;
 
//string InputFile = ((TextBox)dvEditDetail.FindControl("txtInputFile")).Text;
 
//string Comments = ((TextBox)dvEditDetail.FindControl("txtComments")).Text;
 
//string ToDelete = "0";
 
//ExecStore(ShopOutGDCId, ShopCode, InputFile, Comments, ToDelete);
 
//dvEditDetail.Visible = false;
 
////hide the modal popup
 
//mdlPopup.Hide();
 
//DataInfo_Load();
 
//Grid_Load();
 

}

}


catch (Exception ex)

{

ShowError(ex);

}

}


Ah! And the details view is showned up on modalpopup extender.

Robbe Morris replied to João Silva on 05-Sep-13 11:48 AM
To reference a "server side" form element on postback that was created dynamically, that entity must be created again prior to the event you are attempting to reference it in.  ASP.NET will not dynamically recreate your form elements that are not hardcoded as tagged in your aspx page on postback.  This recreation of form elements is typically done at the beginning of the Page_Load event or in the Page_Init event.  A pain of course but it must be done.  This article explains the concept in more detail.

https://www.nullskull.com/a/1617/aspnet-dynamic-textbox--dropdownlist-control-viewstate-to-store-namevaluecollection.aspx

That said, your dynamically created form elements are apart of the postback html form in the Request form elements collection.  So, you can get to the values, you just don't have a complete TextBox, DropDownList, etc. control
João Silva replied to Robbe Morris on 05-Sep-13 01:07 PM
Thanks Robbe for your prompt reply, but I didn't understand how can I get the values? Can you help me out?
Robbe Morris replied to João Silva on 05-Sep-13 01:00 PM
foreach (string key in Request.Form)
{
   Debug.WriteLine(key + " -> " + Request[key].ToString());
}
João Silva replied to Robbe Morris on 06-Sep-13 10:17 AM
Hi again Robbe,

Thank you very much for your help! I have manage to retrieve the values on the controls. But now I am facing another problem with the checkbox...Imagine that there are 3 textbox's and one checkbox, like this order:

Textbox1
Checkbox1
Textbox2
Textbox3

If the checkbox is not checked there is no value on the Request[key] for that control. Therefore the next Request[key] is regarding the textbox2 and not the checkbox1. How can i manage that?
Can you help me out on this one?

Thanks in advance!