I would really appreciate your help on this. This is my problem:
I have a ArrayList of product objects. Each product has a id, name and a supplier.
When I iterate the arraylist and creates a table to put this value into cells I come to the problem that a product can have more than one supplier. If this is the case the id and name are the same but with a different supplier in the arraylist.
My code so far takes care of this by creating empty cells for id and name and put the other supplier in a new cell.
But, it doesn't look good to create new rows for every supplier. What I want is that if a product has more than one supplier I want all the suppliers in the same cell on the row for the product id.
string id = string.Empty;
int count = 0;
public void CreateResultTable(ArrayList result)
{
TableRow row;
TableCell cell;
if (result != null && result.Count > 0)
{
foreach (Item item in result)
{
if (count == 0)
{
row = new TableRow();
id = item.id;
cell = new TableCell();
cell.Text = item.id;
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = item.product;
row.Cells.Add(cell);
cell = new TableCell();
ArrayList levList = item.suppliers;
if (levList != null)
{
string lev = string.Empty;
for (int i = 0; i < levList.Count; i++)
{
lev += levList[i];
}
cell.Text = lev;
row.Cells.Add(cell);
}
else
cell.Text = string.Empty;
row.Cells.Add(cell);
count++;
}
else if (id != item.id)
{
row = new TableRow();
id = item.id;
cell = new TableCell();
cell.Text = item.id;
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = item.product;
row.Cells.Add(cell);
cell = new TableCell();
ArrayList levList = item.suppliers;
if (levList != null)
{
string lev = string.Empty;
for (int i = 0; i < levList.Count; i++)
{
lev += levList[i];
}
cell.Text = lev;
}
else
cell.Text = string.Empty;
row.Cells.Add(cell);
}
else
{
row = new TableRow();
cell = new TableCell();
cell.Text = string.Empty;
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = string.Empty;
row.Cells.Add(cell);
cell = new TableCell();
ArrayList levList = item.suppliers;
if (levList != null)
{
string lev = string.Empty;
for (int i = 0; i < levList.Count; i++)
{
lev += levList[i];
}
cell.Text = lev;
row.Cells.Add(cell);
}
else
cell.Text = string.Empty;
row.Cells.Add(cell);
}
SearchResultLev.Rows.Add(row);
}
SearchResultLev.Visible = true;
SearchResult.Visible = false;
NoSearchResult.Visible = false;
}
else
{
SearchResultLev.Visible = false;
SearchResult.Visible = false;
NoSearchResult.Visible = true;
}
}
Instead of generating a table in code-behind use a GridView.
I've a sample here which uses GridView and a Repeater inside the GridView's Item Template.
The repeater spits out a unbounded list for each supplier.
Markup:
<asp:GridView ID='GridView1' runat='server' AutoGenerateColumns='false'>
<Columns>
<asp:BoundField HeaderText='Product ID' DataField='ID' />
<asp:BoundField HeaderText='Name' DataField='Name' />
<asp:TemplateField HeaderText='Suppliers'>
<ItemTemplate>
<asp:Repeater DataSource='<%# Bind("Suppliers") %>' runat="server" ID='Repeater1'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# Eval("Name") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And code to bind the data (the type definition are below)
GridView1.DataSource = new List<TestProduct>
{
new TestProduct
{
Name = "Test",
ID = "1",
Suppliers = new List<TestSupplier>
{
new TestSupplier { Name="Supplier1" },
new TestSupplier { Name = "Supplier2" },
new TestSupplier { Name =" A very long supplier name"}
}
}
};
GridView1.DataBind();
I've used sample TestProduct and TestSuppliers,
public class TestProduct
{
public String ID { get; set; }
public String Name { get; set; }
public List<TestSupplier> Suppliers { get; set; }
}
public class TestSupplier { public String Name { get; set; }}
sample output:
You can use a Hashtable here:
Hashtable htProductCell = new Hashtable();
if (!htProductCell.Contains(item.product))
{
//add a new row for the item
htProductCell.Add(item.product, cell);
}
else
{
TableCell cell = (TableCell)htProductCell[item.product];
ArrayList levList = item.suppliers;
if (levList != null)
{
string lev = string.Empty;
for (int i = 0; i < levList.Count; i++)
{
lev += levList[i];
}
cell.Text += lev;
row.Cells.Add(cell);
}
}
Related
Here is how i get the values from the gridview controllses, as you can see i do the same way for the label as the textbox, except all textboxes get value and label doesn't and i can't find anything different in the code. The function fillGrid() is just a skeleton for the table to fill it first before placing controllers on it
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
var Column1TextBoxes = Request.Form.AllKeys.Where(k => k.Contains("lblIdDetComp")).ToList(); // Gridview Column 1
var Column2TextBoxes = Request.Form.AllKeys.Where(k => k.Contains("txtComponente")).ToList(); // Gridview Column 2
var Column3TextBoxes = Request.Form.AllKeys.Where(k => k.Contains("txtBase")).ToList(); // Gridview Column 3
var Column4TextBoxes = Request.Form.AllKeys.Where(k => k.Contains("txtComprimento")).ToList(); // Gridview Column 4
if (Request.Form[Column1TextBoxes[j]] != "") comp[j].ID = Convert.ToInt32(Request.Form[Column1TextBoxes[j]]); // Column1 values
else break;
if (Request.Form[Column2TextBoxes[j]] != "") comp[j].Nome = Request.Form[Column2TextBoxes[j]]; // Column2 values
else break;
if (Request.Form[Column3TextBoxes[j]] != "") comp[j].Base = Request.Form[Column3TextBoxes[j]]; // Column3 values
else break;
if (Request.Form[Column4TextBoxes[j]] != "") comp[j].Comprimento = Convert.ToDouble(Request.Form[Column4TextBoxes[j]]); // Column4 values
else break;
j++;
}
}
private void fillGrid()
{
int rowCount = 0;
if (ViewState["rowCount"] != null)
{
rowCount = Convert.ToInt32(ViewState["rowCount"]);
}
DataTable dt = new DataTable();
dt.Columns.Add("IdDetComp",typeof(string));
dt.Columns.Add("Componente", typeof(string));
dt.Columns.Add("Base", typeof(string));
dt.Columns.Add("Comprimento", typeof(string));
for (int i = 0; i < rowCount; i++)
{
dt.Rows.Add("","", "", "");
}
GridView1.DataSource = dt;
GridView1.DataBind();
upDetComps.Update();
}
This is where I add the information to the gridview
int i = 0;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false;
if (e.Row.RowType == DataControlRowType.DataRow)
{
Componente[] Comp = (Componente[])ViewState["Componente"];
if (i < Convert.ToInt32(txtNumComps.Text))
{
Label lblIdDetComp = new Label();
lblIdDetComp.ID = "lblIdDetComp" + (i + 1).ToString();
if (Comp[i] != null) lblIdDetComp.Text = Comp[i].ID.ToString();
TextBox txtComponente = new TextBox();
txtComponente.ID = "txtComponente" + (i + 1).ToString();
if (Comp[i] != null) txtComponente.Text = Comp[i].Nome;
TextBox txtBase = new TextBox();
txtBase.ID = "txtBase" + (i + 1).ToString();
if (Comp[i] != null) txtBase.Text = Comp[i].Base;
TextBox txtComprimento = new TextBox();
txtComprimento.ID = "txtComprimento" + (i + 1).ToString();
if (Comp[i] != null)
{
if (Comp[i].Comprimento != 0)
txtComprimento.Text = Comp[i].Comprimento.ToString();
else
txtComprimento.Text = "";
}
e.Row.Cells[0].Controls.Add(lblIdDetComp);
e.Row.Cells[1].Controls.Add(txtComponente);
e.Row.Cells[2].Controls.Add(txtBase);
e.Row.Cells[3].Controls.Add(txtComprimento);
i++;
}
}
}
My guess would be this is because by default, the Label.AutoSize property is false:
Property Value
Boolean
true if the control adjusts its width to closely fit its contents; otherwise, false.
When added to a form using the designer, the default value is true. When instantiated from code, the default value is false.
So the text is there, it's just size (0,0).
Try setting
lblIdDetComp.AutoSize = true;
I got table, generated by this code (I know it looks bad but it just as a test):
protected void Gen_Load(object sender, EventArgs e)
{
List<string> ParamList = new List<string>();
ParamList.Add("Perforation");
ParamList.Add("Top of perforation");
ParamList.Add("Bottom of perforation");
ParamList.Add("Well radius");
for (int i = 0; i < 4; i++)
{
TableRow row1=new TableRow();
TableCell cell1=new TableCell();
cell1.BorderColor=System.Drawing.Color.DarkGray;
cell1.BorderWidth=2;
cell1.Font.Size = 11;
cell1.Text=ParamList.ElementAt(i);
TableCell cell2 = new TableCell();
cell2.BorderColor=System.Drawing.Color.DarkGray;
cell2.BorderWidth=2;
cell2.Width = 200;
TextBox text1 = new TextBox();
text1.ID = "txtb_1" + i;
text1.Width = cell2.Width;
text1.Height = cell2.Height;
cell2.Controls.Add(text1);
TableCell cell3 = new TableCell();
cell3.BorderColor=System.Drawing.Color.DarkGray;
cell3.BorderWidth=2;
cell3.Width = 200;
DropDownList dlist = new DropDownList();
dlist.ID = "dlist_1" + i;
ListItem li1 = new ListItem("m");
ListItem li2 = new ListItem("ft");
// if (i != 0)
// {
dlist.Items.Add(li1);
dlist.Items.Add(li2);
// }
dlist.Width = cell3.Width;
dlist.Height = cell3.Height;
cell3.Controls.Add(dlist);
row1.Cells.Add(cell1);
row1.Cells.Add(cell2);
row1.Cells.Add(cell3);
row1.ID = "id" + i;
ParamTable.Rows.Add(row1);
}
}
So how do I can get data from dropdownlist and textbox elements on it? I assume that I could use elements ID somehow to call them, but I can't find any example.
UPD: aspx
<asp:Table CssClass="span9" style="margin-top:2px; margin-bottom:5px;" ID="ParamTable" runat="server">
<asp:TableHeaderRow >
<asp:TableHeaderCell Font-Size="Medium" BorderColor="DarkGray" BorderWidth="2px" >Parameters</asp:TableHeaderCell>
<asp:TableHeaderCell Font-Size="Medium" BorderColor="DarkGray" BorderWidth="2px" >Value</asp:TableHeaderCell>
<asp:TableHeaderCell Font-Size="Medium" BorderColor="DarkGray" BorderWidth="2px" >Units</asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow >
</asp:TableRow>
</asp:Table>
See below code to get the value of each row :
for (int i = 0; i < ParamTable.Rows.Count; i++)
{
var textBoxValue = ((TextBox)ParamTable.Rows[i].Cells[1].FindControl("txtb_1" + i)).Text;
var dropDownValue = ((DropDownList)ParamTable.Rows[i].Cells[2].FindControl("dlist_1" + i)).SelectedItem.Text;
}
Note: I don't store values in any list. You can use POCO/Property class as per your requirement.
Update:
Remove <asp:TableRow ></asp:TableRow> from aspx and update forloop as mentioned below:
for (int i = 0; i < ParamTable.Rows.Count - 1; i++)
{
var textBoxValue = ((TextBox)ParamTable.Rows[i].Cells[1].FindControl("txtb_1" + i)).Text;
var dropDownValue = ((DropDownList)ParamTable.Rows[i].Cells[2].FindControl("dlist_1" + i)).SelectedItem.Text;
}
I am working, as a test project, for a simple Inventory System in ASP.NET. In one page, I have to make the page for entering Purchase details! I used the dynamic gridview to ease the data entry. I have used this tutorial and this article but I am having problem in deleting the row in the gridview. I have seen this similar post but it was not helpful.
The aspx code is as below -
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
Purchase Management</h2>
<asp:GridView ID="PurchaseMgmtGridView" runat="server" ShowFooter="True" AutoGenerateColumns="False"
CellPadding="4" ForeColor="#333333" GridLines="None" OnRowDeleting="PurchaseMgmtGridView_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="Item">
<ItemTemplate>
<asp:DropDownList ID="ItemDropDownList" runat="server" AppendDataBoundItems="true">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ItemUnit">
<ItemTemplate>
<asp:DropDownList ID="ItemUnitDropDownList" runat="server" AppendDataBoundItems="true">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rate">
<ItemTemplate>
<asp:TextBox ID="RateTextBox" runat="server">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qty.">
<ItemTemplate>
<asp:TextBox ID="QtyTextBox" runat="server">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="TotalLabel" runat="server">
</asp:Label>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAddNewRow" runat="server" Text=" + " OnClick="ButtonAddNewRow_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
</asp:Content>
And here is the aspx.cs Codes -
namespace SmoothInventoryWeb.Pages.ItemManagment
{
public class Item
{
public string Id { get; set; }
public string Name{get; set;}
}
public class ItemUnit
{
public string Id { get; set; }
public string Name{get; set;}
}
public partial class PurchaseManagementPage : System.Web.UI.Page
{
public List<Item> GetItemList()
{
List<Item> itemList = new List<Item>();
itemList.Add(new Item { Id = "1", Name = "Carpet" });
itemList.Add(new Item { Id = "2", Name = "Pasmina Muffler" });
itemList.Add(new Item { Id = "3", Name = "Large Carpet" });
return itemList;
}
public List<ItemUnit> GetItemUnitList()
{
List<ItemUnit> itemUnitList = new List<ItemUnit>();
itemUnitList.Add(new ItemUnit { Id = "1", Name = "Pieces" });
itemUnitList.Add(new ItemUnit { Id = "2", Name = "Dorzen" });
itemUnitList.Add(new ItemUnit { Id = "3", Name = "Gross" });
return itemUnitList;
}
List<Item> itemList = new List<Item>();
List<ItemUnit> itemUnitList = new List<ItemUnit>();
protected void Page_Load(object sender, EventArgs e)
{
this.itemList = GetItemList();
this.itemUnitList = GetItemUnitList();
if (!Page.IsPostBack)
addFirstRowInGridView();
}
private void FillItemDropDownList(DropDownList dropDownList)
{
if (dropDownList == null)
return;
foreach (Item item in itemList)
{
dropDownList.Items.Add(new ListItem(item.Name.ToString(), item.Id.ToString()));
}
}
private void FillItemUnitDropDownList(DropDownList dropDownList)
{
if (dropDownList == null)
return;
foreach (ItemUnit itemUnit in itemUnitList)
{
dropDownList.Items.Add(new ListItem(itemUnit.Name.ToString(), itemUnit.Id.ToString()));
}
}
protected void ButtonAddNewRow_Click(object sender, EventArgs e)
{
AddNewRow();
}
private void addFirstRowInGridView()
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("Item", typeof(string)));
dataTable.Columns.Add(new DataColumn("ItemUnit", typeof(string)));
dataTable.Columns.Add(new DataColumn("Rate", typeof(string)));
dataTable.Columns.Add(new DataColumn("Qty", typeof(string)));
dataTable.Columns.Add(new DataColumn("Total", typeof(string)));
DataRow dataRow = dataTable.NewRow();
dataRow["Item"] = string.Empty;
dataRow["ItemUnit"] = string.Empty;
dataRow["Rate"] = string.Empty;
dataRow["Qty"] = string.Empty;
dataRow["Total"] = string.Empty;
dataTable.Rows.Add(dataRow);
ViewState["CurrentTable"] = dataTable;
PurchaseMgmtGridView.DataSource = dataTable;
PurchaseMgmtGridView.DataBind();
DropDownList itemDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[0].Cells[0].FindControl("ItemDropDownList");
DropDownList itemUnitDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[0].Cells[1].FindControl("ItemUnitDropDownList");
FillItemDropDownList(itemDropDownList);
FillItemUnitDropDownList(itemUnitDropDownList);
}
private void AddNewRow()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
DropDownList itemDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
DropDownList itemUnitDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
TextBox rateTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
TextBox qtyTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
Label totalLabel =
(Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");
drCurrentRow = dtCurrentTable.NewRow();
dtCurrentTable.Rows[i - 1]["Item"] = itemDropDownList.SelectedItem.ToString();
dtCurrentTable.Rows[i - 1]["ItemUnit"] = itemUnitDropDownList.SelectedItem.ToString();
dtCurrentTable.Rows[i - 1]["Rate"] = rateTextBox.Text;
dtCurrentTable.Rows[i - 1]["Qty"] = qtyTextBox.Text;
dtCurrentTable.Rows[i - 1]["Total"] = totalLabel.Text;
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
PurchaseMgmtGridView.DataSource = dtCurrentTable;
PurchaseMgmtGridView.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
SetPreviousData();
}
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
DropDownList itemDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
DropDownList itemUnitDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
TextBox rateTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
TextBox qtyTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
Label totalLabel =
(Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");
FillItemDropDownList(itemDropDownList);
FillItemUnitDropDownList(itemUnitDropDownList);
if (i < dt.Rows.Count - 1)
{
//itemDropDownList.SelectedValue = dt.Rows[i]["Item"].ToString();
//itemUnitDropDownList.SelectedValue = dt.Rows[i]["ItemUnit"].ToString();
itemDropDownList.ClearSelection();
itemDropDownList.Items.FindByText(dt.Rows[i]["Item"].ToString()).Selected = true;
itemUnitDropDownList.ClearSelection();
itemUnitDropDownList.Items.FindByText(dt.Rows[i]["ItemUnit"].ToString()).Selected = true;
}
rateTextBox.Text = dt.Rows[i]["Rate"].ToString();
qtyTextBox.Text = dt.Rows[i]["Qty"].ToString();
totalLabel.Text = dt.Rows[i]["Total"].ToString();
rowIndex++;
}
}
}
}
protected void PurchaseMgmtGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
SetRowData();
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
int rowIndex = Convert.ToInt32(e.RowIndex);
if (dt.Rows.Count > 1)
{
dt.Rows.Remove(dt.Rows[rowIndex]);
drCurrentRow = dt.NewRow();
ViewState["CurrentTable"] = dt;
PurchaseMgmtGridView.DataSource = dt;
PurchaseMgmtGridView.DataBind();
for (int i = 0; i < PurchaseMgmtGridView.Rows.Count - 1; i++)
{
PurchaseMgmtGridView.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
}
SetPreviousData();
}
}
}
private void SetRowData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
DropDownList itemUnitDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
DropDownList itemDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
TextBox rateTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
TextBox qtyTextBox =
(TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
Label totalLabel =
(Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");
drCurrentRow = dtCurrentTable.NewRow();
//drCurrentRow["RowNumber"] = i + 1;
dtCurrentTable.Rows[i - 1]["Item"] = itemDropDownList.SelectedItem.ToString();
dtCurrentTable.Rows[i - 1]["ItemUnit"] = itemUnitDropDownList.SelectedItem.ToString();
dtCurrentTable.Rows[i - 1]["Rate"] = rateTextBox.Text;
dtCurrentTable.Rows[i - 1]["Qty"] = qtyTextBox.Text;
dtCurrentTable.Rows[i - 1]["Total"] = totalLabel.Text;
rowIndex++;
}
ViewState["CurrentTable"] = dtCurrentTable;
}
}
else
{
Response.Write("ViewState is null");
}
}
}
}
These codes result something like this
But, as soon as I start to delete one of the rows, it gives me this exception -
This exception is thrown from the SetPreviousData() method from the following code -
DropDownList itemDropDownList = (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
Any idea where I got wrong?
P.S. : Code Updated I [supplied the codes for the list of entities i.e.Item and ItemUnit]
It doesn't look like it's actually the deleting of the row in the GridView that's the issue, but rather something else.
First, two things to note - I can't compile because I don't have the definitions for Item and ItemUnit, so I'm doing this by reading the code. Second, I haven't finished my coffee yet! (Update: My coffee is done!)
It looks like the reference to itemDropDownList in SetPreviousData() is null, so look into why that is. It might be easier to use a foreach loop to iterate through the rows of that DataTable to avoid any issues with 0-based indexes and count-1 comparisons, etc. (Update: It still would be easier, but it's not causing the issue.)
Also, not sure if you mean to do this, but the FindControl statement to get the ItemDropDownList is using rowIndex which is always equal to i. (Update: Again, could help just to clean up the code, but it's not a requirement.)
Start by figuring out what i is when it crashes and seeing if that's what you expect and figure out why the FindControl statement isn't working properly. If it's a 0, it may be trying to reading a header row or something where that Dropdown doesn't exist.
Sorry I can't give you a definitive solution, but hopefully this helps.
Solution:
After getting the full code, it was easier to see what happened. Basically, the PurchaseMgmtGridView_RowDeleting method was deleting the DropdownList from the GridView and then SetPreviousData() was trying to read something that didn't exist. The FindControl statement in SetPreviousData was returning NULL as indicated in the error message, but not for the reason I speculated earlier.
Remove the offending lines from the PurchaseMgmtGridView_RowDeleting method and you'll be all set.
protected void PurchaseMgmtGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
SetRowData();
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
int rowIndex = Convert.ToInt32(e.RowIndex);
if (dt.Rows.Count > 1)
{
dt.Rows.Remove(dt.Rows[rowIndex]);
drCurrentRow = dt.NewRow();
ViewState["CurrentTable"] = dt;
PurchaseMgmtGridView.DataSource = dt;
PurchaseMgmtGridView.DataBind();
// Delete this
//for (int i = 0; i < PurchaseMgmtGridView.Rows.Count - 1; i++)
//{
// PurchaseMgmtGridView.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
//}
SetPreviousData();
}
}
}
I think you trying to access on an object reference that points to null.
Try like this
private void SetPreviousData()
{
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count-1; i++)
{
DropDownList itemDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[i].Cells[0].FindControl("ItemDropDownList");
DropDownList itemUnitDropDownList =
(DropDownList)PurchaseMgmtGridView.Rows[i].Cells[1].FindControl("ItemUnitDropDownList");
TextBox rateTextBox =
(TextBox)PurchaseMgmtGridView.Rows[i].Cells[2].FindControl("RateTextBox");
TextBox qtyTextBox =
(TextBox)PurchaseMgmtGridView.Rows[i].Cells[3].FindControl("QtyTextBox");
Label totalLabel =
(Label)PurchaseMgmtGridView.Rows[i].Cells[4].FindControl("TotalLabel");
FillItemDropDownList(itemDropDownList);
FillItemUnitDropDownList(itemUnitDropDownList);
if (i < dt.Rows.Count - 1)
{
//itemDropDownList.SelectedValue = dt.Rows[i]["Item"].ToString();
//itemUnitDropDownList.SelectedValue = dt.Rows[i]["ItemUnit"].ToString();
itemDropDownList.ClearSelection();
itemDropDownList.Items.FindByText(dt.Rows[i]["Item"].ToString()).Selected = true;
itemUnitDropDownList.ClearSelection();
itemUnitDropDownList.Items.FindByText(dt.Rows[i]["ItemUnit"].ToString()).Selected = true;
}
rateTextBox.Text = dt.Rows[i]["Rate"].ToString();
qtyTextBox.Text = dt.Rows[i]["Qty"].ToString();
totalLabel.Text = dt.Rows[i]["Total"].ToString();
}
}
}
}
Refer here for Null Reference Exception
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....
After some minor difficulties with my basic test rating control not working because of the missing inline CSS stylesheet, I am trying to dynamically add a bunch of rating controls in a updatepanel when I click on a button in a different updatepanel. (These panels are both in a parent updatepanel, I have defined the triggers and set the updatemode to conditional). Anyways, when I click the button, he updates the updatepanel with the rating controls, but when I hover over them, he always displays 0 (the current rating), and does not change the rating control star image (filledStarRating). The code relevant to my problem (two methods):
protected void imbformulier_Click(Object sender, ImageClickEventArgs e)
{
imbFormulier.Visible = false;
imbGebruikers.Visible = false;
imbModellen.Visible = false;
pnlGegevens1.Visible = false;
pnlGegevens2.Visible = true;
pnlNavigatie.Visible = true;
pnlEval.Visible = true;
//kijken welk formulier moet ingevuld worden adhv de ddl's en dit meegeven aan de zelfgemaakte klasse
List<EvaluatieFormulier> mijnformulieren = (List<EvaluatieFormulier>)Session["mijnformulieren"];
IEnumerator<EvaluatieFormulier> enumerator = mijnformulieren.GetEnumerator();
EvaluatieFormulier meetegeven = new EvaluatieFormulier();
while (enumerator.MoveNext())
{
if (((enumerator.Current.GebruikergeevalueerdID == ddlGebruikers.SelectedValue) && (enumerator.Current.ModelID == Convert.ToInt32(ddlModellen.SelectedValue))))
{
meetegeven = enumerator.Current;
//Eventueel tekst veranderen als er al was gewerkt aan een bepaalde evaluatie
if (meetegeven.Tijdaangewerkt == 0)
{
lblInfo.Text = "Evaluatie gestart van " + ddlGebruikers.SelectedItem.Text;
lblDatum.Text = "Evaluatie begonnen op: "+ DateTime.Now.Date.ToString("d/M/yyyy") + "(Vandaag)" ;
//updaten in database
Session["aantalminutenaangewerkt"] = 0;
Session["aantalsecondenaangewerkt"] = 0;
timTijdAanGewerkt.Enabled = true;
lblTijd.Visible = true;
}
else
{
lblInfo.Text = "Evaluatie verdergezet van " + ddlGebruikers.SelectedItem.Text;
lblDatum.Text = "Evaluatie laatst gewijzigd : " + meetegeven.Tijdingevuld.ToString();
Session["aantalminutenaangewerkt"] = meetegeven.Tijdaangewerkt;
Session["aantalsecondenaangewerkt"] = 0;
timTijdAanGewerkt.Enabled = true;
lblTijd.Visible = true;
}
}
}
//Rating controls aanmaken voor elke criteria
List<AjaxControlToolkit.Rating> lijstratingcontrols = new List<AjaxControlToolkit.Rating>();
Model modelmetdomeinen = new Model() ;
IEnumerator<Model> modelenum = Database.laadModellenIn().GetEnumerator();
while (modelenum.MoveNext())
{
if (modelenum.Current.ModelID == meetegeven.ModelID)
modelmetdomeinen = modelenum.Current;
}
//foreach (Domein domein in modelmetdomeinen.Domeins)
//{
// foreach (Criterium criterium in domein.Criteriums)
// {
// AjaxControlToolkit.Rating ratingcontrol = new AjaxControlToolkit.Rating();
// ratingcontrol.ID = criterium.CriteriumNaam;
// ratingcontrol.StarCssClass = "ratingStar";
// ratingcontrol.EmptyStarCssClass = "emptyStarRating";
// ratingcontrol.WaitingStarCssClass = "emptyStarRating";
// ratingcontrol.FilledStarCssClass = "filledStarRating";
// ratingcontrol.Changed += new AjaxControlToolkit.RatingEventHandler(rating_Changed);
// ToolkitScriptManager1.RegisterAsyncPostBackControl(ratingcontrol);
// lijstratingcontrols.Add(ratingcontrol);
// }
//}
//Evaluatieform formulier = new Evaluatieform(meetegeven,lijstratingcontrols);
Table evaluatietabel = new Table();
int domeinteller =0;
foreach (Domein domein in modelmetdomeinen.Domeins)
{
domeinteller++;
if (domeinteller < 4)
{
TableRow domeinrij = new TableRow();
TableCell domeintitel = new TableCell();
domeintitel.Text = domeinteller + ". " + domein.DomeinNaam;
domeintitel.BorderStyle = BorderStyle.None;
domeinrij.Cells.Add(domeintitel);
evaluatietabel.Rows.Add(domeinrij);
foreach (Criterium criterium in domein.Criteriums)
{
int criteriumteller = 1;
TableRow criteriumrij = new TableRow();
TableCell criteriumtitel = new TableCell();
TableCell opvulcell = new TableCell();
TableCell ratingcell = new TableCell();
criteriumtitel.BorderStyle = BorderStyle.None;
opvulcell.BorderStyle = BorderStyle.None;
ratingcell.BorderStyle = BorderStyle.None;
criteriumtitel.Text = criteriumteller + ". " + criterium.CriteriumNaam;
AjaxControlToolkit.Rating ratingcontrol = new AjaxControlToolkit.Rating();
ratingcontrol.ID = criterium.CriteriumNaam;
ratingcontrol.StarCssClass = "ratingStar";
ratingcontrol.EmptyStarCssClass = "emptyStarRating";
ratingcontrol.WaitingStarCssClass = "emptyStarRating";
ratingcontrol.FilledStarCssClass = "filledStarRating";
ratingcontrol.Changed += new AjaxControlToolkit.RatingEventHandler(rating_Changed);
ratingcell.Controls.Add(ratingcontrol);
ratingcell.Attributes.Add("runat", "server");
ratingcell.Attributes.Add("onclick", "return false");
criteriumrij.Cells.Add(opvulcell);
criteriumrij.Cells.Add(criteriumtitel);
criteriumrij.Cells.Add(ratingcell);
evaluatietabel.Rows.Add(criteriumrij);
criteriumteller++;
}
}
}
evaluatietabel.BorderStyle = BorderStyle.None;
pnlEval.ContentTemplateContainer.Controls.Add(evaluatietabel);
Session["formulieractief"] = true;
pnlEval.Update();
pnlGegevens1.Update();
pnlGegevens2.Update();
}
I'm also adding the link to an image that shows my problem, so that you can see it for yourself:
We had the same issue recently and the problem was that the latest version of the AjaxControltoolkit seems to require a ToolkitScriptManager instead of the normal ScriptManager.
So just try changing your
asp:ScriptManager tag to
asp:ToolKitScriptManager or
ajax:ToolKitScriptManager
or whatever your namespace is.