problem with the nested gridview asp.net/C# - asp.net

I have a gridview1 which is the parent gridview and I want to insert another gridview2 which is child gridview inside every row of parent gridview
This is the code in the .aspx
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="gridView2" runat="server">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This is the code that I have added inside the RowDataBound Event and i'm just binding the gridview2 with the arraylist which is filtered data depending upon the contents of each row's invoice number
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (GridViewRow gridviewrow in GridView1.Rows)
{
gridView2.AutoGenerateColumns = true;
String x = gridviewrow.Cells[1].Text;
softwareTitlesList = SoftwareListRetrieve();
ArrayList titles = new ArrayList();
foreach (SoftwareTitles softwareTitle in softwareTitlesList)
{
if (softwareTitle.InvoiceNumber.Contains(x))
titles.Add(softwareTitle.SoftwareTitle);
}
gridView2.DataSource = titles;
gridView2.DataBind();
}
}
}
But nothing seems to be happening.
Please help me
Thanks in anticipation

One problem is that you are doing this inside the RowDataBound Event. This is going to be fired for every row in GridView1 that is bound to the datasource. You are essentially resetting the DataSource for GridView2 every time. Try using the DataBound Event of the gridview instead.

RowDataBound event fire when Rows bind the data. you have to do like...
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
System.Data.DataRowView dr = (System.Data.DataRowView)e.Row.DataItem;
gridView2.AutoGenerateColumns = true;
String x = dr["yourColumnName"].ToString();
softwareTitlesList = SoftwareListRetrieve();
ArrayList titles = new ArrayList();
foreach (SoftwareTitles softwareTitle in softwareTitlesList)
{
if (softwareTitle.InvoiceNumber.Contains(x))
titles.Add(softwareTitle.SoftwareTitle);
}
GridView gridView2 = (GridView)e.Row.Findcontrol("gridView2");//add this
gridView2.DataSource = titles;
gridView2.DataBind();
}
}
Edit for comments:
GridView gridView2 = (GridView)e.Row.Findcontrol("gridView2");// add this line

Related

how to change the gridview row value after button click event

I have a table in four columns see screenshot here:
But I need two columns in that table name and gender see screenshot here:
Display in this type but I have required after click the button row value will change in GridView button out side in GridView e.g. row value 1,2 can instead male and female that is my requirement.
You need to fetch that data from database in dataset or datatable and assign that as DataSource to the GridView and call DataBind on that GridView. Now in RowDataBound event compare the value and assign value to UI label / literal based on that.
Below is GridView in aspx page.
<asp:GridView runat="server" AutoGenerateColumns="false" ID="GridView1" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Employee Name">
<ItemTemplate>
<asp:Literal ID="ltrlEmpName" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Employee Gender">
<ItemTemplate>
<asp:Literal ID="ltrlEmpGender" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In code behind, lets say you want to assign the datasource to this GridView in page load or any other method. Below will be its code. Note that in sample here I have taken dummy DataTable and filled values for simplicity, you need to fill that DataTable from db values.
protected void Page_Load(object sender, EventArgs e)
{
// Dummy data table below, that needs to be replaced by datatable / dataset fetched from database.
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("EmpName", typeof(string)));
dt.Columns.Add(new DataColumn("EmpGender", typeof(int)));
DataRow dr1 = dt.NewRow();
dr1["EmpName"] = "Romesh";
dr1["EmpGender"] = 1;
dt.Rows.Add(dr1);
DataRow dr2 = dt.NewRow();
dr2["EmpName"] = "Sandya";
dr2["EmpGender"] = 2;
dt.Rows.Add(dr2);
// Bind the datasource to gridview.
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
System.Web.UI.WebControls.Literal ltrlEmpName = (System.Web.UI.WebControls.Literal)e.Row.FindControl("ltrlEmpName");
System.Web.UI.WebControls.Literal ltrlEmpGender = (System.Web.UI.WebControls.Literal)e.Row.FindControl("ltrlEmpGender");
// Bind employee name to its label.
ltrlEmpName.Text = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpName"));
// Bind employee gender to its label based on its value.
if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpGender")) == "1")
{
ltrlEmpGender.Text = "Male";
}
else if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpGender")) == "2")
{
ltrlEmpGender.Text = "Female";
}
else
{
ltrlEmpGender.Text = "Other";
}
}
}
You will get out as Table as below.

how to delete a row in gridview if using template field

I have tried so many times but i am not able to delete a row in GRID VIEW. I didn't create any database.I am just storing all the values of the text field in the GRID VIEW.If i want to delete a row in the GRID VIEW using template field button means,what will be the solution.
This is the way i am storing and populating values in GridView.
DataSet ds = new DataSet();
DataRow dr = ds.Tables[0].NewRow();
dr[0] = lbltxtcustomer.Text;
dr[1] = FNtxt.Text;
dr[2] = LNtxt.Text;
dr[3] = DrpdownMonth.Text + "/" + DrpdownDay.Text + "/" + DrpdownYear.Text;
dr[4] = lbltxtage.Text;
dr[5] = txtEmail.Text;
dr[6] = TxtPhone.Text;
dr[7] = Txtlocation.Text;
ds.Tables[0].Rows.Add(dr);
BindGrid()
;
Try This
HTML Markup
Below is the HTML Markup of the APS.Net GridView. Here I am making use the CommandFieldand OnRowDeleting event to delete the GridView Row. Hence I will apply the JavaScript Confirmation Box to the CommandFieldDelete Button itself.
<asp:GridView ID="GridView1" CssClass = "Grid" runat="server" OnRowDeleting="OnRowDeleting" AutoGenerateColumns = "false" OnRowDataBound = "OnRowDataBound">
<Columns>
<asp:BoundField DataField="Item" HeaderText="Item" />
<asp:BoundField DataField="Price" HeaderText="Price" />
<asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
</Columns>
</asp:GridView>
Applying the JavaScript Confirmation Box to the GridView CommandField
Delete Button
To apply the JavaScript Confirmation Box, I am looking for the Button in the Controls of the GridView Cell Index 2 since it has the CommandField. Once
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string item = e.Row.Cells[0].Text;
foreach (Button button in e.Row.Cells[2].Controls.OfType<Button>())
{
if (button.CommandName == "Delete")
{
button.Attributes["onclick"] = "if(!confirm('Do you want to delete " + item + "?')){ return false; };";
}
}
}
}
Delete the ASP.Net GridView Row using CommandField and OnRowDeleting
event
Below is the code to delete the ASP.Net GridView Row using OnRowDeleting event
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
DataTable dt = ViewState["dt"] as DataTable;
dt.Rows[index].Delete();
ViewState["dt"] = dt;
BindGrid();
}

Linkbutton click in a asp:GridView cell does not trigger OnRowCommand event

UI Feature: I have a GridView with few columns. Most important column is PcCode, which shows a string value for each row.
Expected: When I click on one of the cell from a row of that PcCode column another GridView should be displayed. However, when I am trying to use a asp:LinkButton for a cell, things just don't work. RowCommand does not get triggered when I click on a asp:LinkButton in the GridView cell. Where am I doing things wrong? Which way the expected functionality can be achieved? Thanks in advance for helping out a newbie.
In the following code I was trying to get a RowIndex and pass it through the CommandArgument and use a CommandName.
.aspx code
<asp:GridView ID="_UIProfitcenterTotalGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AllowPaging="True" PageSize="22" ShowFooter="True" AutoGenerateColumns="False"
DataKeyNames="ProfitcenterCode" EnableViewState="False"
OnRowDataBound="_UIProfitcenterTotalGridView_RowDataBound"
OnPageIndexChanging="_UIProfitcenterTotalGridView_PageIndexChanging"
OnRowCommand="_UIProfitcenterTotalGridView_OnRowCommand">
<Columns>
<asp:TemplateField HeaderText="PcCode" InsertVisible="False"
ShowHeader="False" SortExpression="ProfitcenterCode" FooterText="Total" FooterStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:LinkButton ID="_UIPCCodeLinkButton" runat="server" Text='<%# Eval("ProfitcenterCode") %>'
CommandName="Select"
CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
...
code behind for aspx.cs
protected void _UIProfitcenterTotalGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = _UIProfitcenterTotalGridView.Rows[index];
string ProfitcenterCode = _UIProfitcenterTotalGridView.DataKeys[_UIProfitcenterTotalGridView.SelectedIndex].Values["ProfitcenterCode"].ToString();
}
}
After the row is selected I need to take the selected row's value as a string and compare with a listitem to show a new GridView.
Tried
Using Link_Button_Click(Object sender, EventArgs e) and the following but failed.
protected void _UIProfitcenterTotalGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{string ProfitcenterCode = ((GridViewRow)(((LinkButton)e.CommandSource).NamingContainer)).Cells[2].Text;
}
}
I tried to use LinkButton_Click() event instead of RowCommand as jason suggested:
protected void LinkButton_Click(Object sender, EventArgs e)
{
LinkButton button = (LinkButton)sender;
GridViewRow row = (GridViewRow)button.NamingContainer;
if (row != null)
{
string theValue = ((LinkButton)sender).CommandArgument.ToString();
...
...
//code for the extra thing I needed to do after selecting a cell value.
}
}
However I still had the problem, which I figured out. The problem was the LinkButton was not binding to the rows thefore, it could not pass any value on selection. What was missing was the following code:
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton linkButton = new LinkButton();
linkButton.Text = e.Row.Cells[0].Text; //value of the first column from the grid
linkButton.Enabled = true;
linkButton.Click += new EventHandler(LinkButton_Click); //triggering the LinkButton event here.
e.Row.Cells[0].Controls.Add(linkButton);
}
You can use the sender object ( the link button that calls the event) and get the parent row from the gridview. Example:
Protected Sub linkButton_click(ByVal sender As Object, ByVal e As EventArgs)
'First cast the sender to a link button
Dim btn As LinkButton = CType(sender, LinkButton)
'now, if there is a command arguement, you can get that like this
Dim id As String = btn.CommandArgument
'to get the gridviewrow that the button is on:
Dim row As GridViewRow = CType(btn.NamingContainer, GridViewRow)
End Sub
It was hard to follow exactly what you were looking for, so if i missed something let me know and I will add it.
protected void linkButton_click(object sender, EventArgs e)
{
//First cast the sender to a link button
LinkButton btn = (LinkButton)sender;
//now, if there is a command arguement, you can get that like this
string id = btn.CommandArgument;
//to get the gridviewrow that the button is on:
GridViewRow row = (GridViewRow)btn.NamingContainer;
}
And change your linkbutton to:
<asp:LinkButton OnClick="linkButton_click" ID="_UIPCCodeLinkButton"
runat="server" Text='<%# Eval("ProfitcenterCode") %>'
CommandName="Select"
CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'>

Fill datagrid with paging enabled in asp.net

I have datagrid with paging enabled that can have 10 rows per page. Also I have DataTable with 16 rows. I want to fill the datagrid dynamically with 'for' loop to go over all the DataTable and fill the DataGrid.
I understand that there is a problem when the counter will hit row 11. Do I need to change the page of the datagrid when counter will be 11? Because it doesnt let me add more than 10 rows in the datagrid.
Would appriciate if someone can tell me how to implement it.
Thanks in advance,
Greg
This is pretty much how I'd do it. I'm not using a for as the conditional checking of checkboxes is in ItemDataBound, by doing it this way the DataGrid will do all the paging for me.
Markup:
<asp:DataGrid runat="server" ID="MyDataGrid" AllowPaging="true" PageSize="10" OnPageIndexChanged="MyDataGrid_PageIndexChanged" OnItemDataBound="MyDataGrid_ItemDataBound" Autogeneratecolumns="false">
<Columns>
<asp:BoundColumn DataField="Number" HeaderText="Number" />
<asp:TemplateColumn>
<ItemTemplate>
<asp:CheckBox runat="server" ID="CheckBox" />
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
DataTable numberDataTable;
if (!IsPostBack)
{
// Build a 16-row DataTable
numberDataTable = new DataTable();
numberDataTable.Columns.Add(new DataColumn("Number"));
for (int c = 1; c < 17; c++)
{
DataRow numberDataRow = numberDataTable.NewRow();
numberDataRow[0] = c;
numberDataTable.Rows.Add(numberDataRow);
}
ViewState.Add("Data", numberDataTable);
// DataBind the table into the DataGrid
MyDataGrid.DataSource = numberDataTable;
MyDataGrid.DataBind();
}
}
protected void MyDataGrid_PageIndexChanged(object sender, DataGridPageChangedEventArgs e)
{
DataTable numberDataTable;
// Get the DataTable out of Viewstate
numberDataTable = (DataTable)ViewState["Data"];
// Set the new page number
MyDataGrid.CurrentPageIndex = e.NewPageIndex;
// Bind the grid
MyDataGrid.DataSource = numberDataTable;
MyDataGrid.DataBind();
}
protected void MyDataGrid_ItemDataBound(object sender, DataGridItemEventArgs e)
{
DataRow numberDataRow;
// Selective checking of the CheckBox
// Only do this for Item and ALternatingItem, we don't do this for headers, footers etc
if (e.Item.ItemType == ListItemType.Item | e.Item.ItemType == ListItemType.AlternatingItem)
{
numberDataRow = ((DataRowView)e.Item.DataItem).Row;
// Check if we have an even number
if ((int.Parse(numberDataRow[0].ToString()) % 2) == 0)
{
// Find our checkbox control in the DataGrid for the current row and check it
CheckBox checkBox = (CheckBox)e.Item.FindControl("CheckBox");
checkBox.Checked = true;
}
}
}
This gives:

ASP.Net: drop down list and data source created dynamically

I have about 10 drop down list controls that get populated. Instead of copying/pasting and modifying a few fields on each, I would like to create them programmatically. Can this be done?
Here is what one of them looks like. I would like to programmatically add 10 dropdownlist controls and their respective SqlDataSource controls.
<asp:SqlDataSource ID = "ddlDAGender" runat=server
ConnectionString="<%$ ConnectionStrings:test1ConnectionString %>"
SelectCommand = "select GenderID,Gender from mylookupGender"
>
</asp:SqlDataSource>
<asp:Label ID="Label3" runat="server" Text="Gender"></asp:Label>
<asp:DropDownList ID="ddlGender" runat="server"
DataSourceid="ddlDAGender"
DataTextField="Gender" DataValueField="GenderID"
>
</asp:DropDownList>
You can always create your controls dynamically. In this case though, if all your drop down lists are different, I'm not sure it's saving you anything, since you'll still have to assign them individual ID's and datasources.
Here's what the code might look like:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindDropDownLists();
}
}
protected void Page_Init(object sender, EventArgs e)
{
SqlDataSource sqlDS = new SqlDataSource();
sqlDS.ConnectionString = ConfigurationManager.ConnectionStrings[0].ToString();
sqlDS.SelectCommand = "select GenderID,Gender from mylookupGender";
form1.Controls.Add(sqlDS);
DropDownList ddl = new DropDownList();
ddl.ID = "dddlGender";
ddl.DataSource = sqlDS;
ddl.DataTextField = "Gender";
ddl.DataValueField = "GenderID";
form1.Controls.Add(ddl);
// ... Repeat above code 9 times or put in a for loop if they're all the same...
}
private void BindDropDownLists()
{
foreach (Control ctl in form1.Controls)
{
if (ctl is DropDownList)
{
(ctl as DropDownList).DataBind();
}
}
}

Resources