asp.net content lost in dynamically generated table - c#

I'm trying to use an ajax panel to add keep multiple images added to table cells dynamically. Thing is when I add the second image, the first one dissapears.
Its really just a silly example to try and get ajax controls working for another project.
I'm putting an image of Bill Gates in row 3, column 3 and an image of Steve Jobs in row 1, column 5. I have a button to place each image.
I can't seem to get both to display at the same time.
I have written a function to generate the cell id (GenerateTableCellID), as I've been told I would need to to this. Also there is a function to extract the cell and row in a tuple (GetColumnAndRow).
I'm not sure how to use a Session object to save the data. I thought using AJAX would be the answer, though I think I'm missing a major aspect of it.
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div id="tablePlaceHolder" runat="server"></div>
<asp:Button ID="tblButton2" runat="server" Text="Add Steve Jobs" OnClick="tblButton_Click_Jobs" />
<asp:Button ID="tblButton" runat="server" Text="Add Bill Gates" OnClick="tblButton_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Init(object sender, EventArgs e)
{
int tableSize = 5;
var t = new HtmlTable();
t.ID = "myTable";
var placeHolderURL = "http://wiki.tripwireinteractive.com/images/4/47/Placeholder.png";
for (int r = 0; r < tableSize; r++)
{
var tableRow = new HtmlTableRow();
tableRow.ID = "row_" + r.ToString();
for (int c = 0; c < tableSize; c++)
{
var tableCell = new HtmlTableCell();
var id = GenerateTableCellID(r, c);
tableCell.ID = id;
tableCell.Height = "20";
tableCell.Width = "20";
tableCell.InnerHtml = string.Format("<img src='{0}' width='20' height='20' />", placeHolderURL);
tableRow.Controls.Add(tableCell);
}
t.Controls.Add(tableRow);
}
tablePlaceHolder.Controls.Add(t);
}
protected void tblButton_Click(object sender, EventArgs e)
{
int c =2;
int r = 2;
var id = GenerateTableCellID(c, r);
var image = GenerateImage("http://www.mnn.com/sites/default/files/billgates.jpg");
var cell = (HtmlTableCell)UpdatePanel2.FindControl(id);
cell.InnerHtml = "";
cell.Controls.Add(image);
}
protected void tblButton_Click_Jobs(object sender, EventArgs e)
{
int c = 4;
int r = 0;
var id = GenerateTableCellID(c, r);
var image = GenerateImage("http://images.boomsbeat.com/data/images/full/209/jobs-jpg.jpg");
var cell = (HtmlTableCell)UpdatePanel2.FindControl(id);
cell.InnerHtml = "";
cell.Controls.Add(image);
}
protected Image GenerateImage(string url)
{
var image = new Image();
image.ImageUrl = url;
image.Width = 20;
image.Height = 20;
return image;
}
protected string GenerateTableCellID(int c, int r)
{
return "column_" + c.ToString() + "_row_" + r.ToString();
}
protected Tuple<int, int> GetColumnAndRow(string tableCellID)
{
string[] splitString = tableCellID.Split('_');
int column, row;
if (Int32.TryParse(splitString[1], out column) && Int32.TryParse(splitString[3], out row))
{
return new Tuple<int, int>(column, row);
}
else
{
return null;
}
}

It is because at every update you clear the html present before by cell.InnerHtml = ""; remove this and try
protected void tblButton_Click_Jobs(object sender, EventArgs e)
{
int c = 4;
int r = 0;
var id = GenerateTableCellID(c, r);
var image = GenerateImage("http://images.boomsbeat.com/data/images/full/209/jobs-jpg.jpg");
var cell = (HtmlTableCell)UpdatePanel2.FindControl(id);
//cell.InnerHtml = "";
cell.Controls.Add(image);
}

As mentioned on the Page LifyCycle your table is created everytime when you do reload page (does not matter is this postback or not). Also you could read this post. In other words, it is not proper way store your data in the dynamic generated controls, because you lose your data on page load.
But if it is necessary for you could use AJAX methods ($.get and $.post, not UpdatePanel) to get data from the backend and add this to generated control on the client side

Related

Looping Through a Dynamic Table and extract cell values c#

I am creating a dynamic table with X amount of rows and 2 columns. This is being stored in the view state.
How can I get the values of each cell per row?
Please see my code example:
<p>How many rows?<asp:TextBox ID="txtNoSitesDeployed" runat="server"></asp:TextBox><asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /></p>
<asp:Table ID="dt" runat="server">
</asp:Table>
<asp:Button ID="btnGenerateEmail" runat="server" Text="Generate Email Content Bulk" onclick="btnGenerateEmail_Click" />
<p>
<asp:Label ID="lblTemplate" runat="server" Text=""></asp:Label>
</p>
Please see code-behind:
public partial class _Default : System.Web.UI.Page
{
protected int Rows
{
get
{
return ViewState["Rows"] != null ? (int)ViewState["Rows"] : 0;
}
set
{
ViewState["Rows"] = value;
}
}
protected int Columns
{
get
{
return ViewState["Columns"] != null ? (int)ViewState["Columns"] : 0;
}
set
{
ViewState["Columns"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
this.Rows = Int32.Parse(txtNoSitesDeployed.Text);
this.Columns = 2;
}
}
protected void Button1_Click (object sender, System.EventArgs e)
{
// Total number of rows.
int rowCnt;
// Current row count.
int rowCtr;
// Total number of cells per row (columns).
int cellCtr;
// Current cell counter.
int cellCnt;
rowCnt = Rows;
for(rowCtr=1; rowCtr <= rowCnt; rowCtr++)
{
// Create a new row and add it to the table.
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
var txtSiteName = new TextBox();
txtSiteName.ID = "txtSiteName-" + rowCtr;
txtSiteName.ToolTip = "Enter site name";
cell1.Controls.Add(txtSiteName);
//add cell to row
row.Cells.Add(cell1);
TableCell cell2 = new TableCell();
var ddltBU = new DropDownList();
ddltBU.ID = "ddltBU-" + rowCtr;
ddltBU.Items.Add(new ListItem("fruit", "fruit"));
cell2.Controls.Add(ddltBU);
//add cell to row
row.Cells.Add(cell2);
//add row to dt
dt.Rows.Add(row);
}
}
protected void btnGenerateEmail_Click(object sender, EventArgs e)
{
foreach(TableRow row in dt.Rows)
{
foreach(TableCell cell in dt.Rows)
{
Response.Write(cell.Text);
}
}
}
}
I can't seem to access the cell values.
Any help would be greatly appreciated

Loop all textbox and collect values in c# asp.net

I'm trying to get a list of strings from the database.
For each string in the list i want to add a label & textbox to the page.
On button submit I want to collect the textbox value as well as the corresponding label value then save it to the database.
I need help retrieving the values from the textboxes.
What I have so far:
Panel1 is on the aspx page
protected List<string> items = MyClass.GetItems();
protected void Page_Load(object sender, EventArgs e)
{
GenerateItemsTable();
}
private void GenerateItemsTable()
{
Table table = new Table();
table.ID = "Table1";
//PlaceHolder1.Controls.Add(table);
Panel1.Controls.Add(table);
foreach (var x in items)
{
TableRow row = new TableRow();
for (int y = 0; y < 1; y++)
{
TableCell labelCell = new TableCell();
labelCell.Controls.Add(CreateLabel(x));
labelCell.CssClass = "tdLabel";
row.Cells.Add(labelCell);
TableCell txbCell = new TableCell();
txbCell.Controls.Add(CreateRadNumericTextBox(x));
txbCell.Width = 30;
row.Cells.Add(txbCell);
TableCell dataTypeCell = new TableCell();
dataTypeCell.Text = "<span style='font-size: 10px; color: #777'>(student count)</span>";
dataTypeCell.Width = 100;
row.Cells.Add(dataTypeCell);
TableCell fourthCell = new TableCell();
if (x == items[items.Count - 1])
{
RadButton rb = new RadButton();
rb.ID = "submit";
rb.Text = "Submit Guidance";
rb.Skin = "Forest";
rb.Click += new EventHandler(submit_Click);
rb.AutoPostBack = true;
fourthCell.Controls.Add(rb);
row.Cells.Add(fourthCell);
}
else
{
row.Cells.Add(fourthCell);
}
}
table.Rows.Add(row);
}
}
private RadNumericTextBox CreateRadNumericTextBox(string x)
{
RadNumericTextBox rntb = new RadNumericTextBox();
rntb.ID = x;
rntb.Width = 40;
return rntb;
}
private Label CreateLabel(string x)
{
Label l = new Label();
l.ID = "label_" + x;
l.Text = "<label>" + x + "</label>";
return l;
}
protected void submit_Click(object sender, EventArgs e)
{
foreach (Control x in FindControl("Panel1").FindControl("Table1").Controls)
{
if (x is RadNumericTextBox)
{
//how to get the data??????/
}
}
}
(thanks to those that actually read the whole post)
-----------------updated solution--------------------------------------------
I decided to change it and store the list from the db at page_load. With the list stored i loop through the list and use FindControl() to access the textboxes. Something like this..
//a couple containers
protected class ItemVal
{
public int Value { get; set; }
public string Name { get; set; }
}
protected List<ItemVal> items = new List<ItemVal>();
//get the list from that database
protected void GetItems()
{
foreach (var x in MyClass.GetItems())
{
ItemVal i = new ItemVal();
i.Name = x;
items.Add(i);
}
}
//submit
protected void submit_Click(object sender, EventArgs e)
{
foreach (var x in items)
{
RadNumericTextBox rntb = FindControl(x.Name) as RadNumericTextBox;
x.Value = (int)rntb.Value;
}
}
You need to cast x to a RadNumericTextBox and then pull out the property values you want, like this:
RadNumericTextBox theRadNumericTextBox = x as RadNumericTextBox;
string val = theRadNumericTextBox.Text;
Then for the other controls you want, you will need to put if conditions for their types, like this:
if (x is Label)
{
Label theLabel = x as Label;
string valLabel = theLabel.Text;
}
Here is the full code for the method:
protected void submit_Click(object sender, EventArgs e)
{
foreach (Control x in FindControl("Panel1").FindControl("Table1").Controls)
{
Label theLabel;
RadNumericTextBox theRadNumericTextBox;
if (x is RadNumericTextBox)
{
RadNumericTextBox theRadNumericTextBox = x as RadNumericTextBox;
string val = theRadNumericTextBox.Text;
}
if (x is Label)
{
Label theLabel = x as Label;
string valLabel = theLabel.Text;
}
// Either store up in a list or save to the database on each loop; it is recommended to store a list and send all the changes at once for a database save, but that is your choice
}
}

Access the data in Gridview in runtime when it set auto generate?

i imported my data from Excel sheet to grid view.after that i want to put the column header text of my grid view into drop down,but i can't access them
help me plz :-( ;
this is my code but it dose not work :
List<string> lst = new List<string>();
* for (int i = 0; i < dg_excel.Columns.Count; i++)
{
lst.Add(dg_excel.Columns[i].HeaderText);
}
ddl_prd_count.DataSource;
ddl_prd_count.DataBind();
for this * line it says to me there are no columns (column.count = 0)
Check answer on another SO thread Why column count is 0 for GridView to know that why are you not able to access the columns from your grid's Columns collection.
In my opinion, if you want to use auto generated columns then follow this ASP.net forum link - Customizing Auto Generated Columns (GridView) and SO thread How to hide columns in an ASP.NET GridView with auto-generated columns?.
e.g.
have an idea from this code.. i have not checked the proper syntax etc in it.
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
if (IsFillCombo)
{
//fill your list here.
for (int i = 0; i < datasourcetable.Columns.Count; i++)
{
lst.Add(e.Row.Cells[i].Text);
}
IsFillCombo = false;
}
}
}
// Another simplest way to implement this as below: From Question Text
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<Abc> listofAbc = new List<Abc>();
for (int i = 0; i < 10; i++)
{
listofAbc.Add(new Abc
{
ID = i + 1,
Name = "Abc" + (i + 1).ToString()
});
}
GridView1.DataSource = listofAbc;
GridView1.DataBind();
List<string> lst = new List<string>();
for (int i = 0; i < GridView1.HeaderRow.Cells.Count; i++)
{
lst.Add(GridView1.HeaderRow.Cells[i].Text);
System.Diagnostics.Debug.WriteLine(GridView1.HeaderRow.Cells[i].Text);
}
}
}
}
public class Abc
{
public int ID { get; set; }
public string Name { get; set; }
}
you can use following code
List<string> lst = new List<string>();
for (int i = 0; i < dg_excel.HeaderRow.Cells.Count; i++)
{
lst.Add(dg_excel.HeaderRow.Cells[i].Text);
}
ddl_prd_count.DataSource=lst ;
ddl_prd_count.DataBind();
Access gridView1_CellValueChanged event of your grid
and then accesse.Column.FieldName.ToString()

get dynamic checkbox value on button click

i have a page where i create 2 checkboxes dynamically.
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
CheckBox checkBoxCtrl = new CheckBox();
checkBoxCtrl.ID = "checkBoxCtrl" + i;
Tc.Controls.Add(checkBoxCtrl);
tr.Cells.Add(Tc);
}
once they are created in the page load event i have a Ok_button click event which requires to check if the checkbox is checked or not.
protected void Update2_Click(object sender, EventArgs e)
{
if(checkBoxCtrl.checked)
//here i wont be able to get the value
// i get the error the name checkBoxCtrl does not exist..
{
response.write("true");
}
}
but how do i do the check in this case.
thanks
Answer:
this is what needs to be done to get the checkbox values
protected void Update1_Click(object sender, EventArgs e)
{
for(int i = 0; i < ControlPropList.Count; i++)
{
CheckBox chkTest = (CheckBox)xxx.FindControl("checkBoxCtrl" + i);
{
if (chkTest.Checked)
{
Global.logger.Info("Checkbox True = " + chkTest.ID);
}
else
{
Global.logger.Info("Checkbox False = " + chkTest.ID);
}
}
}
}
This should work fine as long as you add the checkboxes to your page in the Page_PreInit method. If you add them after that (Page_Load for example), their values will not be maintained.
Read about the asp.net page lifecycle here:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Consider storing the dynamic checkbox in a local member:
private CheckBox _myCustomCheckbox = new CheckBox();
protected override void OnInit(EventArgs e)
{
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
if (i == 0)
{
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
_myCustomCheckbox.ID = "checkBoxCtrl" + j;
Tc.Controls.Add(_myCustomCheckbox);
tr.Cells.Add(Tc);
}
}
// the row needs added to a page control so that the child control states can be loaded
SomeTableOnThePage.Controls.Add(tr);
base.OnInit(e);
}
protected void Update2_Click(object sender, EventArgs e)
{
if(_myCustomCheckbox.Checked)
{
response.write("true");
}
}
May not be quite what you want, but I had a similar issue, I have a dynamically generated table in ASP.NET page, with dynamically generated CheckBoxes in one column. I have created the data for the table from a collection, and then as the dynamic CB's are created I give them an ID and store them in a second collection, such as an array of CB's.
So when I need to find the Checked value I simply iterate through the collection, and I can find the ones that are Checked.
Also as they were created simultaneously with the data in the dynamic table I was able to easily tie the table data row to the Checkbox value.
This obviously assumes that the dynamic table and CB's were created using some kind of looping.
This may not be the best solution but works for my current needs.

Calculation in DataGridView column

I have a DataGridView in which I want to sum up values from two different columns into a third column.
Example DataGridView:
A B Total
1 2 3
25 35 60
5 -5 0
I want to add (A+B) in total, just after entering values in A & B column or leaving current row. And also want to set Total Column as ReadOnly.
You can do that on CellValidatedEvent and you can apply the same method to RowValidated:
private void dataGridView_CellValidated(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex > -1) {
DataGridViewRow row = dataGridView.Rows[e.RowIndex];
string valueA = row.Cells[columnA.Index].Value.ToString();
string valueB = row.Cells[columnB.Index].Value.ToString();
int result;
if (Int32.TryParse(valueA, out result)
&& Int32.TryParse(valueB, out result)) {
row.Cells[columnTotal.Index].Value = valueA + valueB;
}
}
}
You can set column to ReadOnly in the designer, or like this:
dataGridView.Columns["Total"].ReadOnly = true
You could easily do this
But you should have a dataset or localdatabase connection like SQL
I will assume that you got it and name it
Totaldataset.
Easily done I know it's too late answer but maybe it help some new readers.
Datacolumn column = new Datacolumn ();
column.Columnname = "Total";
Totaldataset.Tables[0].Columns.["Total"].Expression = "a+b";
This is a working example:
public partial class Form1 : Form
{
DataGridView _calcDataGridView;
public Form1()
{
InitializeComponent();
_calcDataGridView = new DataGridView();
this.Controls.Add(_calcDataGridView);
_calcDataGridView.Dock = DockStyle.Fill;
_calcDataGridView.Name = "CalcDataGridView";
_calcDataGridView.CellEndEdit += Calculate;
var aColumn = new DataGridViewTextBoxColumn();
aColumn.Name = "AColumn";
aColumn.HeaderText = "A";
_calcDataGridView.Columns.Add(aColumn);
var bColumn = new DataGridViewTextBoxColumn();
bColumn.Name = "BColumn";
bColumn.HeaderText = "B";
_calcDataGridView.Columns.Add(bColumn);
var totalColumn = new DataGridViewTextBoxColumn();
totalColumn.Name = "TotalColumn";
totalColumn.HeaderText = "Total";
totalColumn.ReadOnly = true;
_calcDataGridView.Columns.Add(totalColumn);
}
private void Calculate(object sender, DataGridViewCellEventArgs e)
{
object a = _calcDataGridView.CurrentRow.Cells["AColumn"].Value;
object b = _calcDataGridView.CurrentRow.Cells["BColumn"].Value;
double aNumber = 0;
double bNumber = 0;
if (a != null)
aNumber = Double.Parse(a.ToString());
if (b != null)
bNumber = Double.Parse(b.ToString());
_calcDataGridView.CurrentRow.Cells["TotalColumn"].Value = aNumber + bNumber;
}
}
If U r using data binding using Eval
than U can just create a method there and on that method just sum those two values.
Like
For Column A
<ItemTemplate>
<%# Eval("A")%>
</ItemTemplate>
for column B
<ItemTemplate>
<%# Eval("B")%>
</ItemTemplate>
For Total
<ItemTemplate>
<%# GetTotal(Eval("A"),Eval("B")) %>
</ItemTemplate>
For total method
private string GetTotal(object A,object B)
{
return (A+B).ToString();
}
hope this will help you.

Categories

Resources