Add a new row dynamically to Table C# - c#

Below is the code that creates a table and dynamically shows items from a database. This work great, I would like to add a row on a onclick event from a button and make the data persistent when I click the button and not lose data. Any help would be appreciated.
Table tb = new Table();
tb.BorderWidth = 1;
tb.Width = new Unit("740px");
tb.BorderStyle = BorderStyle.Solid;
tb.ID = "myTable";
TableRow tr = new TableRow();
TableRow tr2 = new TableRow();
TableRow trEndRow = new TableRow();
foreach (QuestionBuilder QB in GetQuestionsDatabySection)
{
TableCell tc1 = new TableCell();
tc1.Text = OQB.QuestionText;
tc1.BorderWidth = 1;
tr.Cells.Add(tc1);
tb.Rows.Add(tr);
TableCell tc2 = new TableCell();
tc2.Controls.Add(getControl(OQB.DynamicAttributeId, "0"));
tc2.BorderWidth = 1;
tr2.Cells.Add(tc2);
tb.Rows.Add(tr2);
TableCell tcEnd = new TableCell();
Button btn = new Button();
btn.Text = "Add Row";
btn.Attributes.Add("OnClick", "ButtonAddRow_Click");
btn.Attributes.Add("runat", "server");
tcEnd.Controls.Add(btn);
tcEnd.BorderWidth = 1;
trEndRow.Cells.Add(tcEnd);
tb.Rows.Add(trEndRow);
// Add to PlaceHolder
phTable.Controls.Add(tb);
}

Since you're doing a web app in ASP.NET you'll need to use something to manage your state.
Here's a good breakdown from Microsoft on your options: https://msdn.microsoft.com/en-us/library/z1hkazw7.aspx
Depending on the complexity of your data, view state and query strings are pretty common implementations, but that article highlights the advantages and disadvantages of each option. Once you've decided on which option you want to go with, it should be pretty easy to Google an example of how it's used.
Theoretically you could even reload the data from the database on each post back, if you were inclined to do so.

Related

Use dynamic table to display list of string

I tried to display the list of time slots by using dynamic table in C#. However, it does not work properly. Here is my result:
And here is my code
List<AvailableTime> AllTimeSlots = RequestDirector.ListAllAvailableTimes(BookingDate);
foreach (AvailableTime resultTimeslot in AllTimeSlots)
{
TableRow TimeSLotRow = new TableRow();
TableCell TimeSlotCell = new TableCell();
TimeSlotCell.Text = Convert.ToString(resultTimeslot.TimeSlot);
TimeSLotRow.Cells.Add(TimeSlotCell);
Table1.Rows.Add(TimeSLotRow);
}
I want to display 5 time slots each row. Can anybody tell me how I can do that?
Probably something like this :
int i = 0;
TableRow TimeSLotRow = new TableRow();
foreach (AvailableTime resultTimeslot in AllTimeSlots)
{
TableCell TimeSlotCell = new TableCell();
TimeSlotCell.Text = Convert.ToString(resultTimeslot.TimeSlot);
TimeSLotRow.Cells.Add(TimeSlotCell);
i++;
if(i == 5)
{
Table1.Rows.Add(TimeSLotRow);
TimeSLotRow = new TableRow();
i = 0;
}
}

How do I make this table shorter?

I think I'm doing something terribly wrong here. I have a object inside import called oCultivationPlan. It contains data obviously. And I want to create a table which shows the data inside it. However I only want a selected few from that object and not all the data in it. Is there a way to make this shorter? I thought about using foreach or for, but that would loop through all the data inside the object :/ while I only want a selected few.
TableRow tblRow = new TableRow();
TableCell tblc = new TableCell();
tblc.Controls.Add(new LiteralControl("ID"));
TableCell tblc2 = new TableCell();
tblc2.Controls.Add(new LiteralControl(import.oCultivationPlan.iID.ToString()));
tblRow.Controls.Add(tblc);
tblRow.Controls.Add(tblc2);
tblImportPreview.Controls.Add(tblRow);
TableCell tblc3 = new TableCell();
TableCell tblc4 = new TableCell();
tblc3.Controls.Add(new LiteralControl("Description"));
tblc4.Controls.Add(new LiteralControl(import.oCultivationPlan.sDescription.ToString()));
TableRow tblRow2 = new TableRow();
tblRow2.Controls.Add(tblc3);
tblRow2.Controls.Add(tblc4);
tblImportPreview.Controls.Add(tblRow2);
TableCell tblc5 = new TableCell();
TableCell tblc6 = new TableCell();
tblc5.Controls.Add(new LiteralControl("DateCreated"));
tblc6.Controls.Add(new LiteralControl(import.oCultivationPlan.dDateCreated.ToString()));
TableRow tblRow3 = new TableRow();
tblRow3.Controls.Add(tblc5);
tblRow3.Controls.Add(tblc6);
tblImportPreview.Controls.Add(tblRow3);
not a foreach :) but you can use a for loop to get trough it. you should be able to use the code below as a solution for your question :)
its smaller cuz of the loop but it does the exact same thing as what you did. I use the string array to keep all the info you want to get inside the table so that it will be having something to go out after.
For each row you have you got 2 new cells in it and thats why we have the row*2 so the cells can get filled up :)
Hope it works for you and that you can use the solution :)
int _row = 1;
int _cell = 0;
string[] arr = new string[6] { "ID", import.oCultivationPlan.iID.ToString(), "Description", import.oCultivationPlan.sDescription.ToString(), "DateCreated", import.oCultivationPlan.dDateCreated.ToString() };
for (; _row <= 3; _row++)
{
TableRow tblRow = new TableRow();
for (; _cell < _row * 2; _cell++)
{
TableCell tblc = new TableCell();
tblc.Controls.Add(new LiteralControl(arr[_cell]));
tblRow.Controls.Add(tblc);
}
tblImportPreview.Controls.Add(tblRow);
}
I would create a strong typed Class
public Class ImportDto
{
public string RowIdentifier {get; set;}
public string RowValue {get; set;
}
Then as David said, write a filter function to filter data from Import class and map it to ImportValues
public List<ImportDto> FilterImportedData(Import import)
{
var importDto = new List<ImportDto>
{
new ImportDto { RowIdentifier ="ID", RowValue = import.oCultivationPlan.iID.ToString()},
new ImportDto { RowIdentifier ="Description", RowValue = import.oCultivationPlan.sDescription.ToString()}
};
}
Then in the aspx.cs class, just loop through List<ImportDto>and create LiteralControls
foreach(var dto in importDtos)
{
var row = new TableRow();
var identifierCell = new TableCell();
var valueCell = new TableCell();
identifierCell.Controls.Add(new LiteralControl(dto.RowIdentifier));
valueCell.Controls.Add(new LiteralControl(dto.RowValue ));
row.Add(identifierCell);
row.Add(valueCell);
tblImportPreview.Controls.Add(row);
}
That way all you need to do in future to add new filtered data, is to modify your mapping function and add a new ImportDto, and the it will be displayed in the frontend automatically.

Find Control in Dynamic Created Table Row C#

I've created a table row dynamically using one function as shown here.
Table The_Table = Invoice_Table;
TableRow new_Item_Row = new TableRow();
The_Table.Rows.Add(new_Item_Row);
TableCell new_type = new TableCell();
TableCell new_item = new TableCell();
TableCell new_amount = new TableCell();
DropDownList type_List = new DropDownList();
type_List.ID = "type_List";
ListItem Cash = new ListItem();
Cash.Value="Cash";
Cash.Text="Cash/Cheque";
ListItem IVoi = new ListItem();
IVoi.Value="IVoi";
IVoi.Text="Invoice";
type_List.Items.Add(Cash);
type_List.Items.Add(IVoi);
TextBox item_Text = new TextBox();
item_Text.ID = "item_Text";
TextBox amount_Text = new TextBox();
amount_Text.ID = "amount_Text";
new_type.Controls.Add(type_List);
new_item.Controls.Add(item_Text);
new_amount.Controls.Add(amount_Text);
new_Item_Row.Cells.Add(new_type);
new_Item_Row.Cells.Add(new_item);
new_Item_Row.Cells.Add(new_amount);
I then try to access this control later using the following in a different function
DropDownList type_L = Invoice_Table.FindControl("type_List") as DropDownList;
TextBox amount_p = Invoice_Table.FindControl("amount_Text") as TextBox;
TextBox Item_T = Invoice_Table.FindControl("item_Text") as TextBox;
but it is returning
"Object reference not set to an instance of an object."
I assume it is because it can't find the control? But I'm not sure how to fix it.
Sorry for the messiness of adding new cells... I'm new to this and I am not aware of any better way to do this.
The problem is that FindControl is not recursive. You have to call it on the TableCell instance and not the Table itself.
TextBox amount_p = new_amount.FindControl("amount_Text") as TextBox;

Creating Hyperlink in Dynamically Created Table error 'Table' cannot have children of type 'HyperLink'.

I am trying to create a hyperlink in a table cell, this is what I have so far.
I error out with this message, "'Table' cannot have children of type 'HyperLink'."
How can I fix this?
TableRow Label11 = new TableRow();
TableCell Label11TC = new TableCell();
HyperLink P30HL = new HyperLink();
P30HL.NavigateUrl = "http://endor/RequestIT/Remee/test/Details.aspx";
P30HL.Text = (work / dda).ToString("p");
Label11.Cells.Add(Label11TC);
Table1.Controls.Add(P30HL);
You need to place the hyperlink into a table cell instead of the table...
TableRow Label11 = new TableRow();
TableCell Label11TC = new TableCell();
HyperLink P30HL = new HyperLink();
P30HL.NavigateUrl = "http://endor/RequestIT/Remee/test/Details.aspx";
P30HL.Text = (work / dda).ToString("p");
Label11.Cells.Add(Label11TC);
Label11TC.Controls.Add(P30HL);
Almost there Justin Harvey, just some syntax related errors....add the hyperlink to a cell, then add the cell to a row, then add the row to the table.
TableRow tbRow= new TableRow();
TableCell tbCell = new TableCell();
HyperLink hyplnk= new HyperLink();
hyplnk.NavigateUrl = "http://endor/RequestIT/Remee/test/Details.aspx";
hyplnk.Text = (work / dda).ToString("p");
tbCell.Controls.Add(hplink);
tbRow.Controls.Add(tbCell);
TableID.Controls.Add(tbRow); //TabledID is the ID you give the table in the ASPX page
The above worked for me

LINQ to replace foreach in Table creation

I need to create a Table (LINQ to replace foreach in TableRow creation) by adding rows corresponding to objects in a generic list. We can do it as listed below using a foreach loop. How can we achieve this functionality using LINQ without foreach?
Note: One table cell need to be added corresponding to each property in the object.
System.Web.UI.WebControls.Table tableControl = new Table();
foreach (FinancialTransaction transaction in transactionsList)
{
TableRow row = new TableRow();
TableCell cellLineNumber = new TableCell();
cellLineNumber.Text = Convert.ToString(transaction.Line);
row.Cells.Add(cellLineNumber);
TableCell cellEmpID = new TableCell();
cellEmpID.Text = Convert.ToString(transaction.EmpID);
row.Cells.Add(cellEmpID);
TableCell cellSSN = new TableCell();
cellSSN.Text = transaction.SSN;
row.Cells.Add(cellSSN);
tableControl.Rows.Add(row);
}
You can use ForEach LINQ if transactionsList is List, but you could improve readability a little bit:
transactionsList.ForEach(transaction => {
TableRow row = new TableRow();
valueList = new object[] {
transaction.Line,
transaction.EmpID,
transaction.SSN
};
row.Cells.AddRange(valueList.Select(value => CreateCell(value))
.ToArray());
});
private TableCell CreateCell(object cellText)
{
TableCell cell = new TableCell();
cell.Text = Convert.ToString(cellText);
return cell;
}
You can also use Aggregate:
var tableControl = transactionsList.Aggregate(new Table(), (acc, transaction) =>
{
TableRow row = new TableRow();
TableCell cellLineNumber = new TableCell();
cellLineNumber.Text = Convert.ToString(transaction.Line);
row.Cells.Add(cellLineNumber);
TableCell cellEmpID = new TableCell();
cellEmpID.Text = Convert.ToString(transaction.EmpID);
row.Cells.Add(cellEmpID);
TableCell cellSSN = new TableCell();
cellSSN.Text = transaction.SSN;
row.Cells.Add(cellSSN);
acc.Rows.Add(row);
return acc;
});
How about the foreach of Linq itself?
or check this link
It is also possible to create your own Extension Methods

Categories

Resources