I want to add a single row to the table from the two lists. i am getting an error in the second foreach loop. Cannot convert Liability.LiabilityCheckpointInstance to Liability.LiabilityAssignment.
foreach (LiabilityCheckpointInstance ci in value)
{
//foreach (LiabilityAssignment la in value)
//{
var tr = new TableRow();
var tc = new TableCell { Text = ci.CheckGroup };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.IxCheck.ToString() };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.CheckPointInfo.ToString() };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.RejectedBy };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.Role };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.Mistakes.ToString() };
tr.Cells.Add(tc);
//ChkpLiabilityDataTable.Rows.Add(tr);
foreach (LiabilityAssignment la in value )
{
//var tr = new TableRow();
tc = new TableCell { Text = la.LiabileOrganizationName };
tc = new TableCell { Text = la.LiabileOrganizationName };
tr.Cells.Add(tc);
tc = new TableCell { Text = la.LiablePersonName };
tr.Cells.Add(tc);
tc = new TableCell { Text = la.Comment };
tr.Cells.Add(tc);
ChkpLiabilityDataTable.Rows.Add(tr);
}
}
Your foreach loops are:
foreach (LiabilityCheckpointInstance ci in value)
foreach (LiabilityAssignment la in value )
It is looping over the same thing (value) but saying the items in it are different. [1]
I would assume from the context that the second should be looping over ci.something rather than just value.
So you would have:
foreach (LiabilityAssignment la in ci.Something )
Of course you will need to change the Something to whatever your list is.
[1] I should note that the syntax itself is not incorrect. If the items in value is of both types then (eg one is a subtype of the other) it would work fine. This doesn't look like it is the case here though.
This should do the trick for you.
foreach (LiabilityCheckpointInstance ci in value)
{
var tr = new TableRow();
var tc = new TableCell { Text = ci.CheckGroup };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.IxCheck.ToString() };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.CheckPointInfo.ToString() };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.RejectedBy };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.Role };
tr.Cells.Add(tc);
tc = new TableCell { Text = ci.Mistakes.ToString() };
tr.Cells.Add(tc);
// YOU NEED TO BUILD THESE UP FRONT SO YOU CAN LOOP THROUGH THE
// CHILDREN SAFELY BELOW
tr.Cells.Add(new TableCell());
tr.Cells.Add(new TableCell());
tr.Cells.Add(new TableCell());
// I DON'T KNOW IF YOUR PROPERTY IS NAMED LiabilityAssignments OR NOT
// SO REPLACE THAT WITH WHAT EVER IS NECESSARY - BUT IT SHOULD BE THE
// LIST OF LiabilityAssignment ON THE LiabilityCheckpointInstance OBJECT
foreach (LiabilityAssignment la in ci.LiabilityAssignments)
{
tr.Cells[6].Text = la.LiabileOrganizationName;
tr.Cells[7].Text = la.LiablePersonName;
tr.Cells[8].Text = la.Comment;
ChkpLiabilityDataTable.Rows.Add(tr);
}
}
you are using 'value' as the source list for both foreach statements. value apparently contains LiabilityCheckpointInstance objects, so it fails when you try to use it as if it contained LiabilityAssignment objects.
Did you means to sa: foreach (LiabilityAssignment la in ci.)?
Second loop should be
foreach (LiabilityAssignment la in ci)
Related
I want to add some Required Validator on Controls(Textbox as example) in a dynamic asp:table.
Code:
foreach (KeyValuePair<string, string> o in Collection)
{
TableRow Row = new TableRow();
TableCell valueCell = new TableCell();
TableCell Cell = new TableCell();
TextBox txtBox = new TextBox();
TextBox txtBox1 = new TextBox();
txtBox1.ID = o.Key + o.Value;
if (o.Value.Contains("Mandatory"))
{
RequiredFieldValidator req = new RequiredFieldValidator();
req.ErrorMessage = "Required";
req.BorderColor = System.Drawing.Color.Red;
req.ControlToValidate = txtBox1.ID;
req.Enabled = true;
req.Display = ValidatorDisplay.Dynamic;
Cell.Controls.Add(req);
}
valueCell.Controls.Add(txtBox1);
Row.Cells.Add(valueCell);
Row.Cells.Add(Cell);
table.Rows.Add(Row);
}
But i am getting this error:
" System.Web.UnhandledException in System.web.dll"
on the line Row.Cells.Add(Cell);
Can you help me ?
I fix the problem with a Panel which contains the Texbox and the RequireValidatorField.
Panel p = new Panel();
p.Controls.Add(txtBox1);
p.Controls.Add(req);
valueCell.Controls.Add(p);
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;
}
}
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.
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
I have this code
protected void Page_Load(object sender, EventArgs e)
{
TblPrikaz.BorderWidth = 1;
XmlDocument baza = new XmlDocument();
XmlTextReader reader = new XmlTextReader(Server.MapPath("baza.xml"));
baza.Load(reader);
TableRow line = new TableRow();
TableCell id = new TableCell();
TableCell ime = new TableCell();
TableCell prezime = new TableCell();
TableCell godiste = new TableCell();
id.Text = "ID";
ime.Text = "Ime";
prezime.Text = "Prezime";
godiste.Text = "Godiste";
line.BackColor = Color.Green;
line.Cells.Add(id);
line.Cells.Add(ime);
line.Cells.Add(prezime);
line.Cells.Add(godiste);
TblPrikaz.Rows.Add(line);
XmlNodeList popis = baza.GetElementsByTagName("element");
for (int i = 0; i < popis.Count; i++)
{
if (string.Compare(popis[i].Attributes["ID"].Value.ToString(), "0") == 0) continue;
id.Text = popis[i].Attributes["ID"].Value.ToString();
ime.Text = popis[i].ChildNodes[0].InnerText;
prezime.Text = popis[i].ChildNodes[1].InnerText;
godiste.Text = popis[i].ChildNodes[2].InnerText;
line.Cells.Add(id);
line.Cells.Add(ime);
line.Cells.Add(prezime);
line.Cells.Add(godiste);
TblPrikaz.Rows[i].Cells.Add(id);
TblPrikaz.Rows[i].Cells.Add(ime);
TblPrikaz.Rows[i].Cells.Add(prezime);
TblPrikaz.Rows[i].Cells.Add(godiste);
}
}
for some reason, the table only shows the loast row read fromthe document and I have no idea why it is doing that.
Anyone have an idea?
You are not creating a new row on each iteration. Instead, you are updating the existing row.
XmlNodeList popis = baza.GetElementsByTagName( "element" );
for ( int i = 0; i < popis.Count; i++ )
{
var element = popis[i];
if ( element == null || element.Attributes == null )
continue;
if ( element.Attributes["ID"].Value.ToString() == "0" )
continue;
var idCell = new TableCell { Text = element.Attributes["ID"].Value.ToString() };
var imeCell = new TableCell { Text = element.ChildNodes[0].InnerText };
var prezimeCell = new TableCell { Text = element.ChildNodes[1].InnerText };
var godisteCell = new TableCell { Text = element.ChildNodes[2].InnerText };
var row = new TableRow();
row.Cells.Add( idCell );
row.Cells.Add( imeCell );
row.Cells.Add( prezimeCell );
row.Cells.Add( godisteCell );
TblPrikaz.Rows.Add( row );
}
Your table always use the same row and cell objects, you need to create new ones in the loop:
id = new TableCell();
etc....