Nested Repeaters using DataTable - c#

I could not properly bind my child repeater (lvTwo) using a datatable. It always throws a NullReferenceException. On debug mode, my datatable looked fine, any thoughts?
HTML Code:
<asp:Repeater ID="lvOne" runat="server" OnItemDataBound="lvOne_ItemDataBound">
<ItemTemplate>
<div>
I am the one.
</div>
<asp:Repeater ID="lvTwo" runat="server">
<ItemTemplate>
I am the two.
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Code-behind (dtTable to bind for lvOne, dtTable2 to bind for lvTwo):
protected void Page_Load(object sender, EventArgs e)
{
DataTable dtTable = new DataTable();
dtTable.TableName = "T1";
dtTable.Columns.Add("ProjectName");
DataRow dr = dtTable.NewRow();
dr["ProjectName"] = "ThreeSixFive";
dtTable.Rows.Add(dr);
if (!Page.IsPostBack)
{
lvOne.DataSource = dtTable;
lvOne.DataBind();
}
}
protected void lvOne_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DataTable dtTable2 = new DataTable();
dtTable2.TableName = "T2";
dtTable2.Columns.Add("C");
DataRow dr = dtTable2.NewRow();
dr["C"] = "ThreeSixFive";
dtTable2.Rows.Add(dr);
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (dtTable2 != null)
{
lvTwo.DataSource = dtTable2;
lvTwo.DataBind();
}
}
}`

The culprit was due to the unrecognized lvTwo control. It was able to compile due to the control being registered in the designer file, instead I need to use the ff:
var lvTwo = (ListView) e.Item.FindControl("lvTwo");

Related

'ddlItem' has a SelectedValue which is invalid because it does not exist in the list of items. Parameter name: value

I'm getting this error whenever I try to bind data inside gridview dropdownlist.
Here is the aspx code:
<asp:TemplateField HeaderText="Item Description" SortExpression="ddlItem">
<ItemTemplate>
<asp:DropDownList ID="ddlItem" runat="server" Height="25px" Width="200px" SelectedValue='<%# Eval("ddlItem") %>'>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
Here is the code behind (c#):
private void SetInitialRowToGrid()
{
// Initialize and Set initial row of Datatable
var tempDataTable = new DataTable();
tempDataTable.Columns.Add("lblId");
tempDataTable.Columns.Add("ddlItem");
tempDataTable.Columns.Add("txtUnit");
tempDataTable.Columns.Add("txtQty");
tempDataTable.Rows.Add("1", "", "", "");
// Store that datatable into viewstate
ViewState["TempTable"] = tempDataTable;
// Attach Gridview Datasource to datatable
gvItemList.DataSource = tempDataTable;
gvItemList.DataBind(); //Here I'm getting the error.
}
protected void gvItemList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlItem = (e.Row.FindControl("ddlItem") as DropDownList);
Jilu1TableAdapters.tbl_ItemTableAdapter item;
item = new Jilu1TableAdapters.tbl_ItemTableAdapter();
DataTable dt = new DataTable();
dt = item.GetItems();
ddlItem.DataSource = dt;
ddlItem.DataTextField = "Item";
ddlItem.DataValueField = "Item";
ddlItem.DataBind();
ddlItem.Items.Insert(0, new System.Web.UI.WebControls.ListItem("--Select an Item--", "0"));
}
}
protected void ddlSiteID_SelectedIndexChanged(object sender, EventArgs e)
{
Jilu1TableAdapters.tbl_Jr_BOMTableAdapter ds;
ds = new Jilu1TableAdapters.tbl_Jr_BOMTableAdapter();
DataTable dt = new DataTable();
dt = ds.GetVersion(ddlSiteID.SelectedValue);
ddlVersion.DataSource = dt;
ddlVersion.DataValueField = "Version";
ddlVersion.DataTextField = "Version";
ddlVersion.DataBind();
int ver = Convert.ToInt32(ddlVersion.Text);
DataTable dt1 = new DataTable();
dt1 = ds.GetDetails(ddlSiteID.SelectedValue, ver);
foreach (DataRow row in dt1.Rows)
{
txtSiteName.Text = (row["txtSiteName"].ToString());
ddlSiteType.Text = (row["ddlSiteType"].ToString());
txtNoBTS.Text = (row["txtNoBTS"].ToString());
txtNoLinks.Text = (row["txtNoLinks"].ToString());
txtLoadBand.Text = (row["txtLoadBand"].ToString());
ddlEBAvailability.Text = (row["ddlEBAvailability"].ToString());
txtEBPhase.Text = (row["txtEBPhase"].ToString());
txtDGCapacity.Text = (row["txtDGCapacity"].ToString());
txtDGPhase.Text = (row["txtDGPhase"].ToString());
}
gvItemList.DataSource = dt1;
gvItemList.DataBind();
}
I tried putting Text = 'Bind("ddlItem")', Datasourse, SelectedValue but still no luck.
Any help will be greatly appreciated.
In this code ,
<asp:DropDownList ID="ddlItem" runat="server" Height="25px" Width="200px"
SelectedValue='<%# Eval("ddlItem") %>'>
</asp:DropDownList>
you set SelectedValue to '<%# Eval("ddlItem") %>' but ddlItem is not exist in your datasource fields .
Put the correct field which you want to display in your dropdownlist .
And I suggest you to set DataTextField and DataValueField of your DropDownList .
Set it like DataTextField="ddlItem" DataValueField="ddlItem" .
Hope it's help for you :)
Your way is wrong
try this below way
protected void gvItemList_RowDataBound(object sender, GridViewEditEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList ddList= (DropDownList)e.Row.FindControl("ddlItem");
//bind dropdownlist
DataTable dt = con.GetData("select * from tablename");//selected data from db or anywhere for bind ddl
ddList.DataSource = dt;
ddList.DataTextField = "YourCOLName";//id
ddList.DataValueField = "YourCOLName";//displaying name
ddList.DataBind();
DataRowView dr = e.Row.DataItem as DataRowView;
ddList.SelectedValue = dr["YourCOLName"].ToString();// default selected value
}
}
}

asp.net repeater for each row

I have a repeater that retrieve data from my db.
some of the results are getting a null value in a specific column due to
a join query and its fine.
I would like to go over each row and if the result is null for the specific
row i want to change the css for this row.
Now for the code:
<asp:Repeater ID="repRequests" OnItemDataBound="repRequests_ItemDataBound" runat="server">
<ItemTemplate>
<asp:Label ID="lbltest" runat="server" Text='<%#Eval("val_name") %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
C#:
if (!IsPostBack)
{
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("check_accepted", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#val_name", Session["valName"].ToString());
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
repRequests.DataSource = dr;
repRequests.DataBind();
}
}
How to write this ?
protected void repRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
**//what i want to get:**
if (dr["accepted_id"] == Null) // a column from the db table
{
repRequests.attribute["class"] = "Some Class"
}
}
}
Thanks for the helpers !
You can try the following. If the data source is a DataReader object, you must cast e.Item.DataItem as type DBDataRecord (from System.Data.Common)
protected void repRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
System.Data.Common.DbDataRecord dataRow = e.Item.DataItem as System.Data.Common.DbDataRecord;
if (dataRow["accepted_id"] == DBNull.Value || dataRow["accepted_id"] == null) // a column from the db table
{
// I am not sure how to you get repRequests. but you can find the control using e.Row.Item.FindControl() function
repRequests.attribute["class"] = "Some Class";
}
}
}
EDIT
Further to your questions, if you want to change the css of a perticular row, if some value is null, you cannot set css to repeater or repeater item directly. What you need to do is add a top level panel to the ItemTemplate like this
<ItemTemplate>
<asp:Panel runat="server" ID="panelRow">
<asp:Label ID="lbltest" runat="server" Text='<%#Eval("val_name") %>'></asp:Label>
</asp:Panel>
</ItemTemplate>
Then you can change the css of the panel like below
protected void repRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
System.Data.Common.DbDataRecord dataRow = e.Item.DataItem as System.Data.Common.DbDataRecord;
if (dataRow["accepted_id"] == DBNull.Value || dataRow["accepted_id"] == null) // a column from the db table
{
Panel panelRow = e.Item.FindControl("panelRow") as Panel;
panelRow.CssClass = "yourcssclass";
}
}
}
If not, you can use IsNull in your query.
SqlCommand cmd = new SqlCommand("select IsNull(something,zero) from sometable",connectionstring)
SqlDatareader dr = cmd.ExecuteReader();
while(dr.Read())
{
if(dr.GetString(0)=="zero")
{
repRequests.attribute["class"] = "Some Class";
}
}
Here is link example of DbDataRecord when you bind repeater control with sqldatareader.
Also note that repRequests.attribute["class"] = "Some Class" this means you are applying CSS Class to the repeater control. You need to change the CssClass label which is used as item of repeater control.
protected void repRequests_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DbDataRecord dbr = (DbDataRecord)e.Item.DataItem;
if( Convert.ToString(DataBinder.Eval(dbr, "accepted_id")) == null )
((Label)e.Item.FindControl("lbltest")).CssClass = "Some Class";
}
}

How to add new grid rows without clearing existing data

My Code successfully adds new rows to the gridview on the button click, but clears all entered values in existing rows. I understand that, the existing data should be stored into a ViewState, but I do not know where/how to achieve this.
ASPX:
<asp:GridView ID="gvCommissions" runat="server" AutoGenerateColumns="False"
CellPadding="4" ForeColor="#333333" AutoGenerateDeleteButton="True">
<Columns>
<asp:TemplateField HeaderText="S.NO" ItemStyle-Width="5%">
<ItemTemplate>
<asp:Label ID="lblSno" runat="server" Width="98%"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="NAME" ItemStyle-Width="30%">
<ItemTemplate>
<asp:TextBox ID="txtName" runat="server" Width="98%"></asp:TextBox>
</ItemTemplate>
</Columns>
</asp:GridView>
CODE BEHIND:
DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if(ViewState["gvCommissions"] != null)
dt = (DataTable)ViewState["gvCommissions"];
if (!Page.IsPostBack)
{
GridViewStructure();
AddNewRow();
}
else
{
dt = (DataTable)ViewState["gvCommissions"];
}
ViewState["gvCommissions"] = dt;
}
private void GridViewStructure()
{
dt = new DataTable();
dt.Columns.Add("sno");
dt.Columns.Add("name");
}
private void AddNewRow()
{
dt = new DataTable();
dt.Columns.Add("sno");
dt.Columns.Add("name");
foreach (GridViewRow gvRow in gvCommissions.Rows)
{
DataRow drCurrentRow = dt.NewRow();
drCurrentRow["sno"] = ((Label)gvRow.FindControl("lblSno")).Text;
drCurrentRow["name"] = ((TextBox)gvRow.FindControl("txtName")).Text;
dt.Rows.Add(drCurrentRow);
}
DataRow dr = dt.NewRow();
dr["sno"] = "";
dr["name"] = "";
dt.Rows.Add(dr);
gvCommissions.DataSource = dt;
gvCommissions.DataBind();
}
protected void btnAddRow_Click(object sender, EventArgs e)
{
AddNewRow();
}
Its Simple first check if there is any row in gridview then add rows value in datatable then add the empty row. As below.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
AddNewRow();
}
}
private void AddNewRow()
{
DataTable dt = new DatatTable();
dt.Columns.Add("sno");
dt.Columns.Add("name");
foreach (GridViewRow gvRow in gvCommissions.Rows)
{
DataRow dr = dt.NewRow();
dr["sno"] = ((Label)gvRow.FindControl("lblSno")).Text;
dr["name"] = ((Label)gvRow.FindControl("txtName")).Text;
dt.Rows.Add(dr);
}
DataRow dr1 = dt.NewRow();
dr1["sno"] = "";
dr1["name"] = "";
dt.Rows.Add(dr1);
gvCommissions.DataSource = dt;
gvCommissions.DataBind();
}
protected void btnAddRow_Click(object sender, EventArgs e)
{
AddNewRow();
}
You missed one part. Each time the page is loaded, you are saving the table to view state, and forgot to use it!
Try to retrieve it from viewstate at page load like this:
protected void Page_Load(object sender, EventArgs e)
{
if(ViewState["gvCommissions"] != null) dt = (DataTable)ViewState["gvCommissions"];
if (!Page.IsPostBack)
{
GridViewStructure();
AddNewRow();
}
else
{
dt = (DataTable)ViewState["gvCommissions"];
}
ViewState["gvCommissions"] = dt;
}
One thing I would add, it is not a good idea to save the table in view state.

GridView row not updating, text from textbox in gridview edit template not coming

I have grid view in which I want to update row but it is not happening. The datasource is a DataTable. Please help.
Below is the markup
<asp:GridView ID="GrdV" runat="server" AutoGenerateColumns="false"
OnRowEditing="GrdV_RowEditing" OnRowUpdating="GrdV_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="Clip Description">
<ItemTemplate>
<asp:Label ID="lblDescrptn" runat="server" Text='<%# Bind("Description") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="descTbx" runat="server" Text='<%# Bind("Description") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>
and this is code behind
protected void GrdV_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
// Retrieve the row being edited.
int index = GrdV.EditIndex;
GridViewRow row = GrdV.Rows[index];
TextBox t1 = row.FindControl("descTbx") as TextBox;
DataTable dt = (DataTable)Session["tmdataTable"];
dt.Rows[index]["Description"] = t1.Text; //Description is a column of my DataTable
dt.AcceptChanges();
GrdV.EditIndex = -1;
GrdV.DataSource = dt;
GrdV.DataBind();
}
On debugging , I find that textbox is passing empty string t1.Text ="" even after I have filled textbox with new values.
I think the error is in line
TextBox t1 = row.FindControl("descTbx") as TextBox;
PageLoad code
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GrdV.DataSource = Session["tmdataTable"];
GrdV.DataBind();
}
DataTable Finaldt = getTable();
GrdV.DataSource = Finaldt;
GrdV.DataBind();
Session["tmdataTable"] = Finaldt;
}
EditIndex isn't available, you need e.RowIndex from the GridViewUpdateEventArgs
// Retrieve the row being edited.
DataTable dt = (DataTable)Session["tmdataTable"];
GridViewRow row = GrdV.Rows[e.RowIndex];
TextBox t1 = row.FindControl("descTbx") as TextBox;
dt.Rows[row.DataItemIndex]["Description"] = t1.Text; //Description is a column of my DataTable
dt.AcceptChanges();
GrdV.EditIndex = -1;
GrdV.DataSource = dt;
GrdV.DataBind();
Alter your code a bit and check. Change EditIndex to e.RowIndex
protected void GrdV_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = GrdV.Rows[e.RowIndex]; // this line is changed
TextBox t1 = row.FindControl("descTbx") as TextBox;
DataTable dt = (DataTable)Session["tmdataTable"];
dt.Rows[row.DataItemIndex]["Description"] = t1.Text; //Description is a column of my DataTable
dt.AcceptChanges();
GrdV.EditIndex = -1;
GrdV.DataSource = dt;
GrdV.DataBind();
}
Have you done this:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GrdV.DataSource = Session["tmdataTable"];
GrdV.DataBind();
}
}
protected void GrdV_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.Item is GridDataItem)
{
// Retrieve the row being edited.
int index = GrdV.EditIndex;
GridViewRow row = GrdV.Rows[index];
TextBox t1 = row.FindControl("descTbx") as TextBox;
DataTable dt = (DataTable)Session["tmdataTable"];
dt.Rows[index]["Description"] = t1.Text; //Description is a column of my DataTable
dt.AcceptChanges();
GrdV.EditIndex = -1;
GrdV.DataSource = dt;
GrdV.DataBind();
}
}

Binding dropdownlist inside gridview edititemtemplate

I'm not able to bind my dropdownlist present in edititem template . I am getting null reference when i try to access it.
My design:
<asp:TemplateField HeaderText ="Category">
<ItemTemplate >
<asp:Label ID="drpcategory" Text ='<%#Bind("category") %>' runat ="server" />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="drpcategory1" AppendDataBoundItems="True" runat="server" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
My code behind:
protected void gv_RowEditing(object sender, GridViewEditEventArgs e)
{
gv_table1.EditIndex = e.NewEditIndex;
DropDownList drpcategory1 = ((DropDownList)gv_table1.Rows[e.NewEditIndex].Cells[8].FindControl("drpcategory1"));
//BindDropDown(drpcategory1);
dt = con.GetData("Select category_name from category");
String str = gv_table1.Rows[e.NewEditIndex].FindControl("drpcategory1").GetType().ToString();
//((DropDownList)gv_table1.Rows[e.NewEditIndex].Cells[8].FindControl("drpcategory1")).DataSource = dt;
drpcategory1.DataSource = dt;
drpcategory1.DataTextField = "category_name";
drpcategory1.DataValueField = "category_name";
drpcategory1.DataBind();
this.setgrid();
}
I've tried looking on the net and tried many things in vain. I am new to asp. Thanks in advance. I would like the dropdown to be bound only when user enters edit mode.
Code Behind: Tested Code and also set dropdown-list selected value on edit mode
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList ddList= (DropDownList)e.Row.FindControl("drpcategory1");
//bind dropdown-list
DataTable dt = con.GetData("Select category_name from category");
ddList.DataSource = dt;
ddList.DataTextField = "category_name";
ddList.DataValueField = "category_name";
ddList.DataBind();
DataRowView dr = e.Row.DataItem as DataRowView;
//ddList.SelectedItem.Text = dr["category_name"].ToString();
ddList.SelectedValue = dr["category_name"].ToString();
}
}
}
protected void gv_RowEditing(object sender, GridViewEditEventArgs e)
{
gv.EditIndex = e.NewEditIndex;
gridviewBind();// your gridview binding function
}
I do it like this. In which, Name and Id are two fields of Company object:
HTML Code:
<asp:TemplateField HeaderText="Công ty">
<EditItemTemplate>
<asp:DropDownList ID="ddlCompanyEdit" DataSource="<%# PopulateddlCompanyEdit() %>" DataValueField="Id" DataTextField="Name" runat="server"></asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lbCompany" runat="server" Text='<%#Bind("Company") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
C# code behind:
protected IEnumerable<Company> PopulateddlCompanyEdit()
{
using (var bkDb = new BrickKilnDb())
{
return bkDb.Companies.ToList();
}
}
protected void gvProject_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
string Active = "";
if (e.Row.DataItem != null)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
Label lblEditActive = (Label)e.Row.FindControl("lblUP_ET_ActiveStatus");
if (lblEditActive.Text != string.Empty)
{
Active = lblEditActive.Text.Trim();
}
DropDownList ddlActive = (DropDownList)e.Row.FindControl("ddlUP_ET_ActiveStatus");
ddlActive.Items.Clear();
ddlActive.Items.Add("True");
ddlActive.Items.Add("False");
ddlActive.DataBind();
ddlActive.Items.FindByText(Active).Selected = true;
}
}
}
catch (Exception ex)
{
throw ex;
}
}
The event RowEditing occurs just before a row is edited.
You should use the RowDataBound event instead.
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (gv.EditIndex == e.Row.RowIndex &&
e.Row.RowType==DataControlRowType.DataRow)
{
DropDownList drpcategory1 = (DropDownList)e.Row.FindControl("drpcategory1");
//bind the control
}
}
You have to use RowDataBound event to bind the dropdown control for edited row. Please use below method in RowDataBound event.
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == DataControlRowState.Edit)
{
DropDownList drpcategory1 = (DropDownList)e.Row.FindControl("drpcategory1");
DataTable dt = con.GetData("Select category_name from category");
drpcategory1.DataSource = dt;
drpcategory1.DataTextField = "category_name";
drpcategory1.DataValueField = "category_name";
drpcategory1.DataBind();
}
}
Hope this will help you.

Categories

Resources