Add Required Validator on Dynamic Asp:net Table - c#

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);

Related

Dynamically Created TextBox AutoPostBack on TextChanged but Event Function is not called

everybody,
I have been trying for days now to solve this problem with no success.
I have textboxes in table cells which are created dynamically upon button click. Three of these buttons will take a value, calculation method (% or Const Value) and the value to apply respectively. Below is the function which creates these TB's among other controls.
protected void btnAddService_Click(object sender, EventArgs e)
{
TableRow r = new TableRow();
TableCell c0 = new TableCell();
TableCell c1 = new TableCell();
TableCell c2 = new TableCell();
TableCell c3 = new TableCell();
TableCell c4 = new TableCell();
TableCell c5 = new TableCell(); // Management Fees (% or Const)
TableCell c6 = new TableCell(); // Management Fees Value
TableCell c7 = new TableCell(); // Remarks
service s = new service();
if (serCount == 0)
{
tblHeader.Visible = true;
}
// Add the Services DropDownList...
DropDownList ddlS = new DropDownList();
ddlS.ID = "ddlServices" + serCount;
ddlS.Items.Add("Management");
ddlS.Items.Add("MEP");
ddlS.Items.Add("Landscaping");
ddlS.Items.Add("Pest Control");
ddlServices.Add(ddlS);
ddlS.CssClass = "form-control";
ddlS.Width = Unit.Percentage(100);
c0.Controls.Add(ddlS);
c0.Width = Unit.Percentage(15);
s.serviceName = "Management";
// Add Subcontracted Checkbox...
CheckBox chkSubCont = new CheckBox();
chkSubCont.ID = "chkSubCont" + serCount;
chkSubContracted.Add(chkSubCont);
c1.Controls.Add(chkSubCont);
c1.Width = Unit.Percentage(5);
c1.HorizontalAlign = HorizontalAlign.Center;
s.subcontracted = false;
// Add Subcontracted Value...
TextBox txtSubContVal = new TextBox();
txtSubContVal.ID = "txtSubcontractVal" + serCount;
txtSubContVal.CssClass = "form-control";
txtSubContVal.Attributes.Add("placeholder", "0.000");
txtSubContVal.Style.Add("text-align", "right");
txtSubcontValue.Add(txtSubContVal);
c2.Controls.Add(txtSubContVal);
c2.Width = Unit.Percentage(10);
s.subcontValue = 0;
// Add Management Fees Type (% or Const)...
DropDownList ddlMFT = new DropDownList();
ddlMFT.Items.Add("%");
ddlMFT.Items.Add("Value");
ddlMFT.CssClass = "form-control";
ddlMFT.Width = Unit.Percentage(100);
ddlMFT.ID = "ddlManFeesType" + serCount;
ddlManFeesType.Add(ddlMFT);
c5.Controls.Add(ddlMFT);
c5.Width = Unit.Percentage(5);
// Add Management Fees Value...
TextBox txtMFVal = new TextBox();
txtMFVal.CssClass = "form-control";
txtMFVal.Attributes.Add("placeholder", "0.000");
txtMFVal.Style.Add("text-align", "right");
txtMFVal.Width = Unit.Percentage(100);
// txtMFVal.ID = "txtManFeesValue" + serCount;
txtMFVal.AutoPostBack = true;
txtMFVal.TextChanged += new EventHandler(txtManFeesVal_TextChange);
txtManFeesValue.Add(txtMFVal);
c6.Controls.Add(txtMFVal);
c6.Width = Unit.Percentage(10);
// Add Manpower Value...
TextBox txtManp = new TextBox();
txtManp.ID = "txtManpower" + serCount;
txtManp.CssClass = "form-control";
txtManp.Attributes.Add("placeholder", "0");
txtManp.Style.Add("text-align", "center");
txtManPower.Add(txtManp);
c3.Controls.Add(txtManp);
c3.Width = Unit.Percentage(10);
s.manPower = 0;
// Add Quoted Value...
TextBox txtQuotVal = new TextBox();
txtQuotVal.ID = "txtQuotedValue" + serCount;
txtQuotVal.CssClass += "form-control";
// txtQuotVal.Text = "0.000";
txtQuotVal.Attributes.Add("placeholder", "0.000");
txtQuotVal.Style.Add("text-align", "right");
txtQuotVal.AutoPostBack = true;
txtQuotVal.ClientIDMode = ClientIDMode.Static;
txtQuotVal.TextChanged += (o, ep) => {
TextBox t = sender as TextBox;
if (t.Text == "")
{
t.Text = "0.000";
}
txtPrjValue.Text = (int.Parse(txtPrjValue.Text) + int.Parse(t.Text)).ToString();
};
txtQuotValue.Add(txtQuotVal);
c4.Controls.Add(txtQuotVal);
c4.Width = Unit.Percentage(10);
// Add Remarks Box...
TextBox txtRem = new TextBox();
txtRem.ID = "txtRemarks" + serCount;
txtRem.CssClass += "form-control";
txtRem.ClientIDMode = ClientIDMode.Static;
txtRem.Width = Unit.Percentage(100);
txtRemarks.Add(txtRem);
c7.Controls.Add(txtRem);
c7.Width = Unit.Percentage(35);
s.quotedValue = 0;
// Add the cells to the new row...
r.Cells.Add(c0);
r.Cells.Add(c1);
r.Cells.Add(c2);
r.Cells.Add(c5);
r.Cells.Add(c6);
r.Cells.Add(c3);
r.Cells.Add(c4);
r.Cells.Add(c7);
// Add the new row...
tblServices.Rows.Add(r);
serCount++;
// Postback to refresh contents from Server Side...
string scriptRefresh = "document.getElementById('" + btnASPClickMe.ClientID + "').click();";
Page.ClientScript.RegisterStartupScript(typeof(Page), "refreshscript", scriptRefresh, true);
}
Upon TextChanged of txtMFVal text, it does PostBack but it doesn't call the attached event handler, shown below:
protected void txtManFeesVal_TextChange(object sender, EventArgs e)
{
TextBox txtMFV = sender as TextBox;
// Get the parent cell of the TextBox...
TableRow tr = txtMFV.Parent.Parent as TableRow;
TextBox txtSCV = tr.Cells[2].Controls[0] as TextBox;
TextBox txtMFT = tr.Cells[5].Controls[0] as TextBox;
double scv = Double.Parse(txtSCV.Text);
double mfv = Double.Parse(txtMFV.Text);
double v = 0;
if (txtMFT.Text == "%")
{
v = (scv * mfv) / 100;
}
else
{
v = scv + mfv;
}
TextBox txtQP = tr.Cells[6].Controls[0] as TextBox;
txtQP.Text = v.ToString();
// Postback to refresh contents from Server Side...
string scriptRefresh = "document.getElementById('" + btnASPClickMe.ClientID + "').click();";
Page.ClientScript.RegisterStartupScript(typeof(Page), "refreshscript", scriptRefresh, true);
}
I have tried so many tricks I have found on the net and all didn't work.
Please, help.
Thanks,

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;

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

Nested lists and foreach loops

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)

c# asp.net table row always going in the same row

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....

Categories

Resources