How to bind 2 databse tables to gridview and one as dropdown - c#

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Width="301px" AllowPaging="True" OnRowDataBound="GridView1_RowDataBound" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" >
<Columns>
<asp:BoundField DataField="StudentName" HeaderText="StudentName" SortExpression="StudentName" />
<%-- <asp:BoundField DataField="StudentDOB" HeaderText="StudentDOB" SortExpression="StudentDOB" />--%>
<asp:TemplateField HeaderText="DeptName">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" Width="100px"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#String.Format("~/Employee/EmployeeEditPage.aspx?StudentID={0}", Eval("StudentID"))%>'> Edit</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server">Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
above is my design:
below I wrote my code for to display the database, which have table departmenttable and another table studenttable to show the values into the grid. in department table I have departmentname(dept_name)
which should come in dropdown inside the gridview..but it showing error..pls help..
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
SqlConnection con = new SqlConnection(DataBase.GetConnection());
con.Open();
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList ddList = (DropDownList)e.Row.FindControl("dept_name");
//bind dropdownlist
DataTable dt = con.GetData("select dept_name from dbo.DepartmentTable");
ddList.DataSource = dt;
ddList.DataTextField = "dept_name";
ddList.DataValueField = "DeptName";
ddList.DataBind();
DataRowView dr = e.Row.DataItem as DataRowView;
//ddList.SelectedItem.Text = dr["YourCOLName"].ToString();
ddList.SelectedValue = dr["DeptName"].ToString();
con.Close();
GridView1.DataBind();
}
}
}

For binding dropdownlist in GriView first you need to find it by its id. In your sample code, you are trying to find something which is not dropdownlist.
Try this,
DropDownList ddList = (e.Row.FindControl("DropDownList1") as DropDownList);
if(ddList != null)
{
//your code
}

Related

Not properly set Data in GridView

i'm trying retrieve data from database and dispay in gridview. for create Header i'm using HeaderTemplet Tag. but in gridview always first column of employee id is blank.
my code is as under of aspx page:
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<tr>
<th style="padding: 2.5px; width: 10%;" >eid</th>
<th style="padding: 2.5px; width: 55%;" >First Name</th>
<th style="padding: 2.5px;" >Last Name</th>
</HeaderTemplate>
</asp:TemplateField>
<asp:BoundField DataField="idemp" />
<asp:BoundField DataField="fname" />
<asp:BoundField DataField="lname" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="GridView2" runat="server" Width="99%" GridLines="Both" AutoGenerateColumns="false" CssClass="ChildGrid">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
code behind:
namespace WebApplication2
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Populate the GridView.
bindGridview();
}
}
public void bindGridview()
{
DataTable dt = new DataTable();
string constr = #"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
MySqlCommand cmd = new MySqlCommand("select idemp,fname,lname from emp", con);
con.Open();
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count >0)
{
GridView1.DataSource = dt;
GridView1.DataBind();
con.Close();
}
}
}
//RowDataBound Event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Checking the RowType of the Row
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = new DataTable();
string constr = #"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
con.Open();
GridView child_gridview = (GridView)e.Row.FindControl("GridView2");
String CountryId = (e.Row.RowIndex+1).ToString();
MySqlCommand cmd = new MySqlCommand("select salary,post from emp where idemp="+CountryId, con);
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count > 0)
{
child_gridview.DataSource = dt;
child_gridview.DataBind();
}
}
}
}
}
}
and output is as under:
first column of gridview is always empty.when using HeaderTemplet tag.
and i want to achieve like this.
If you want the nested GridView to span multiple columns, you have to do that in the RowDataBound of the parent GridView. In there you can set the colspan and remove the last 2 cells.
So if you have a GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<%# Eval("Id") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<%# Eval("Name") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Saldy">
<ItemTemplate>
<asp:GridView ID="NestedGrid" runat="server" AutoGenerateColumns="true">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Address">
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
</asp:TemplateField>
</Columns>
</asp:GridView>
And the RowDataBound event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a normal datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the row back to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//use findcontrol to locate the nested gridview
GridView gv = e.Row.FindControl("NestedGrid") as GridView;
//bind data to the nested grid
gv.DataSource = source;
gv.DataBind();
//set the column span to 3 on the cell that has the nested gridview
e.Row.Cells[2].ColumnSpan = 3;
//hide the last 2 cells
e.Row.Cells[3].Visible = false;
e.Row.Cells[4].Visible = false;
}
}
The only problem is that the cells of the parent and child do not match in width, so you may need to set a fixed width for those columns.
Seems like you are retrieving the data just fine but not displaying it properly.
You are mistakenly using TemplateField to define headers.
You can simply do the following:
<asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="idemp" headertext="Employee ID" />
<asp:BoundField DataField="fname" headertext="First Name" />
<asp:BoundField DataField="lname" headertext="Last Name" />
</Columns>
</asp:GridView>
As you can see the Header names are defined right in bound column.
Enjoy, and let me know if still having issue

How to remove a row from gridview on Row Command?

I have a grid view where data is dyanmically added. I need an onRowCommand where the selected row will be deleted. I need the row to be deleted only from the grid view.
protected void LoadDataTable()
{
string header = lblHeader.Text;
string aa = tv.SelectedNode.Parent.Value;
string child = tv.SelectedNode.Text;
string parent = tv.SelectedNode.Parent.Text;
var dt = new DataTable();
dt.Columns.Clear();
dt.Rows.Clear();
dt.Columns.Add("TargetGLId");
dt.Columns.Add("TargetHead");
dt.Columns.Add("Parent");
dt.Columns.Add("Header");
foreach (GridViewRow row in gvBudgetSetup.Rows)
{
var lblheader = (Label)row.FindControl("lblHeader");
var lblparticular = (Label)row.FindControl("lblParticular");
var lblGlId = (Label)row.FindControl("lblGLId");
var lblparent = (Label)row.FindControl("lblParent");
var dr = dt.NewRow();
dr["TargetHead"] = lblparticular.Text;
dr["TargetGLID"] = lblGlId.Text;
dr["Parent"] = lblparent.Text;
dr["Header"] = lblHeader.Text;
dt.Rows.Add(dr);
}
var dr1 = dt.NewRow();
dr1["TargetHead"] = child;
dr1["TargetGLID"] = tv.SelectedValue;
dr1["Parent"] = parent;
dr1["Header"] = header;
dt.Rows.Add(dr1);
gvBudgetSetup.DataSource = null;
gvBudgetSetup.DataBind();
gvBudgetSetup.DataSource = dt;
gvBudgetSetup.DataBind();
}
I have tried this code to delete the row but it is not working.
protected void gvBudgetSetup_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete1")
{
// gvBudgetSetup.DeleteRow(e.Row.RowIndex);
GridViewRow gvr = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
int getRowIndex = gvr.RowIndex;
gvBudgetSetup.DeleteRow(getRowIndex);
}
}
This is the Gridview created. The gridview is not connected to any database. The data in the gridview is added from the back-end codes.
<asp:GridView ID="gvBudgetSetup" runat="server" CssClass="table1" AutoGenerateColumns="false" ShowFooter="true" OnSelectedIndexChanged="gvBudgetSetup_SelectedIndexChanged"
ShowHeaderWhenEmpty="true" OnRowDataBound="gvBudgetSetup_RowDataBound" OnRowCommand="gvBudgetSetup_RowCommand" OnRowDeleting="gvBudgetSetup_RowDeleting" Width="100%">
<FooterStyle CssClass="GridFooter" />
<RowStyle CssClass="GridItem" />
<columns>
<asp:TemplateField HeaderText="Sn">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="GL Id">
<ItemTemplate>
<asp:Label ID="lblGLId" runat="server" Text='<%# Bind("TargetGLID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header">
<ItemTemplate>
<asp:Label ID="lblHeader" runat="server" Text='<%# Bind("Header") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Parent">
<ItemTemplate>
<asp:Label ID="lblParent" runat="server" Text='<%# Bind("Parent") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Child">
<ItemTemplate>
<asp:Label ID="lblParticular" runat="server" Text='<%# Bind("TargetHead") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:LinkButton runat="server" Text="Delete" CommandName="Delete1"
ID="lnkDelete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</columns>
<EmptyDataTemplate>
"There are no data to display..."
</EmptyDataTemplate>
</asp:GridView>
Better way to do is have a flag in the data source that one row is flagged(deleted) and bind it again. To delete a datarow from a GridViewEvent, you have to re bind the datasource again.
Introduce a Flag column in your data source
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
//Update the flag in datasource using the CommandArgument value
//Bind the datasource again.
}
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
}
GridViewRow gvr = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
int getRowIndex = gvr.RowIndex;
gvBudgetSetup.DeleteRow(getRowIndex);
Use this updated code

Row command with Link button in GridView

I have two GridViews. GridView1 contains 2 link buttons in a column. When I select a link button in GridView1, the details of the link button should be displayed in GridView2.
GridView2 contains a column with radio buttons. I need to fill the radio buttons dynamically from the database.
How can I fill the Radio button list of GridView2 by using GridView1_RowCommand? Or Can I get it from the RowDataBound event of GridView2?
code behind:
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Yes")
{
GridViewRow gvRow = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
int RowIndex = gvRow.RowIndex;
Int32 iAppID = Convert.ToInt32(GridView1.DataKeys[gvRow.RowIndex].Value.ToString());
dset = userApps.UserSelectedApp(iUserID, iAppID);
if (dset.Tables[0].Rows.Count > 0)
{
GridViewRow gRow = GridView2.Rows[RowIndex];//I need to create object to this Gridview2, and fill the radiobutton list with some values
RadioButtonList rdbtnSubPlans = (RadioButtonList)e.gRow.Cells[2].FindControl("rdbSubPlans");
ds = userApps.UpgradePlans(iUserID, iAppID);
if (ds != null)
{
rdbtnSubPlans.DataSource = ds;
rdbtnSubPlans.DataValueField = "PlanID";
rdbtnSubPlans.DataTextField = "Plans";
rdbtnSubPlans.DataBind();
}
}
}
if (e.CommandName == "No")
{}
dtset = user.UserSelectedAppication(iUserID, iAppID);
GridView2.DataSource = dtset;
GridView2.DataBind();
MultiView1.SetActiveView(viewRenewOrUpdate);
}
}
ASPX code for the GridViews
<asp:GridView ID="GridView1" runat="server" DataKeyNames="ApplicationID"
OnRowDataBound="GridView1_RowDataBound" OnRowCommand="GridView1_RowCommand"
OnSorting="GridView1_Sorting" OnDataBound="GridView1_DataBound"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField HeaderText="S.No" ItemStyle-HorizontalAlign="center" HeaderStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:Label ID="l1" runat="server" Text="1"></asp:Label>
</ItemTemplate>
<HeaderStyle Width="10%" />
</asp:TemplateField>
< Some Bound Fields>
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="lnkYes" runat="server" Text="Yes"
CssClass="lnkbtn" Visible="false" commandname="Yes" Width="100px" >
</asp:LinkButton>
<asp:LinkButton ID="lnkNo" runat="server" CssClass="lnkbtn" Text="No"
Visible="false" commandname="No" ToolTip="No and Yes current plan" Width="100px" >
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:GridView ID="GridView2" runat="server" DataKeyNames="ApplicationID"
OnRowDataBound="GridView2_RowDataBound">
<Columns>
<asp:BoundField DataField="ApplicationName" HeaderText="Application name">
<HeaderStyle Width="30%" />
<ItemStyle CssClass="col" />
</asp:BoundField>
<asp:TemplateField HeaderText="Plans">
<ItemTemplate>
<asp:RadioButtonList ID="rdbSubPlans" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="rdbSubPlan_OnSelectedIndexChanged" Enabled="false">
</asp:RadioButtonList>
</ItemTemplate>
<ItemStyle CssClass="col" />
</Columns>
</asp:GridView>
Fill Gridview2 first, and then do the following corrections:
GridViewRow gRow = GridView2.Rows[0]
RadioButtonList rdbtnPlans = (RadioButtonList)gRow.FindControl("rdbPlans");

Fill GridView with TextBoxes and Dropdownlist from DataTable

I have GridView:
<asp:GridView ID="MyGridView" runat="server" ShowFooter="true"
AutoGenerateColumns="False" Visible="True">
<Columns>
<asp:BoundField DataField="id" ItemStyle-HorizontalAlign="center"/>
<asp:BoundField DataField="fullName" />
<asp:TemplateField HeaderText="situation>">
<ItemTemplate>
<asp:DropDownList ID="dl_situation" runat="server" AppendDataBoundItems="true">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="procesVerbal">
<ItemTemplate>
<asp:TextBox ID="tbNr" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Data">
<ItemTemplate>
<asp:TextBox ID="tbDate" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now I want to fill this Grid with data from database, I have one method that returns datatable with all my data
when I fill mygrid:
MyGridView.DataSource = dataTable;
MyGridView.Databind();
in this case all TextBoxes and DropDownList are null.
In the code below I'm trying to create a function that receives DataTable from database and populates gridview with data. How do I make a foreach statement for dataTable.Rows that will assign text values to TextBox elements and selectedIndex value to DropDownList?
protected bool FillGridWithData(DataTable dataTable)
{bool result;
try
{
foreach (GridViewRow row in MyGridView1.Rows)
{
if (row.RowType != DataControlRowType.DataRow) break;
var ddl = (DropDownList)row.FindControl("dl_situation");
if (ddl != null)
{
ddl.DataSource = PublicStatic.Situation;
ddl.DataTextField = PublicStatic.Name;
ddl.DataValueField = PublicStatic.Code;
ddl.DataBind();
ddl.Items.Insert(0, new ListItem(String.Empty, String.Empty));
ddl.SelectedIndex = //data from datatable;
}
var tb1 = (TextBox)row.FindControl("tbNr");
if (tb1 != null)
tb1.Text =//data from datatable;
var tb2 = (TextBox)row.FindControl("tbDate");
if (tb2 != null)
tb2.Text = //data from datatable;
}
result = true;
}
catch (Exception exception)
{
result = false;
}
return result;
}
The DataField attribute in the bound field must equal to the column name in the datatable.
For binding textboxes in the template field you can use the Eval or Bind Method.
Example:
<asp:TemplateField HeaderText="procesVerbal">
<ItemTemplate>
<asp:TextBox ID="tbNr" Text='<%# Eval("ColumnName") %>' runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
and for binding the dropdown in the gridview, you can use a separate sql datasource. and specify dropdownlist DataSourceID,DataTextField and DataValueField property.
Dropdownlist Example:
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="ddl" runat="server" DataSourceID="SqlDataSource1" DataTextField="ProductName" DataValueField="ProductID" ></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products]"></asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
and if you want to bind the datasource from code behind then you can use RowDataBound event of gridview
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
TextBox t = (TextBox)e.Row.FindControl("ControlID");
t.Text = "Some Text";
}
}

How to find a control in a row and bind it to data

I have a gridview and in the gridview i got a item template as follows
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlProductNames">
</asp:DropDownList>
</ItemTemplate>
Now on every row in the gridview i need to bind this to the data, but i am having trouble finding it and binding it to the data.
The gridview has 4 templatefields with 1 itemtemplate within each template field like this
<asp:TemplateField HeaderText="Product Name" ItemStyle-HorizontalAlign = "Center" >
<ItemTemplate>
<asp:TextBox runat="server" ID="txt1" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Products" ItemStyle-HorizontalAlign = "Center" >
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlProductNames">
</asp:DropDownList>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Image" ItemStyle-HorizontalAlign = "Center" >
<ItemTemplate>
<asp:FileUpload runat="server" ID="image" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Active" ItemStyle-HorizontalAlign = "Center">
<ItemTemplate>
<asp:CheckBox Text="Active" runat="server" ID="active" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
And I am trying to bind the drop down as follows
protected void Grid_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
// Bind Products
Product productManager = new Product();
TList<Product> dsProduct= productManager.GetAll();
DropDownList ddlProducts = Grid.Rows[e.Row.RowIndex].Cells[1].Controls[0].FindControl("ddlProductNames") as DropDownList;
if (dsProduct != null)
{
DataView dvProduct = new DataView(dsProduct.ToDataSet(true).Tables[0]);
dvProduct.Sort = "name asc";
ddlProducts.DataSource = dvBrand;
ddlProducts.DataTextField = "name";
ddlProducts.DataValueField = "productId";
ddlProducts.DataBind();
ListItem li = new ListItem("No Product Selected", "0");
ddlProducts.Items.Insert(0, li);
}
}
I am getting a out of index in the line DropDownList ddlProducts = Grid.Rows[e.Row.RowIndex].Cells[1].Controls[0].FindControl("ddlProductNames") as DropDownList; I am learning this process so i would appreciate some help in terms of what i am doing wrong and what i need to change. I would really appreciate any help.
You must use FindControl to find controls in a TemplateField. You also need to exclude the header-row:
protected void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRow row = ((DataRowView)e.Row.DataItem).Row;
DropDownList ddlProducts = (DropDownList)e.Row.FindControl("ddlProductNames");
ddlProducts.DataSource = someDataSource;
ddlProducts.DataTextField = "name";
ddlProducts.DataValueField = "productId";
ddlProducts.DataBind();
}
}
You also don't need to call productManager.GetAll() for every row in the Grid. You only need to get the products for the current Row. If the source is the same for every row, you should create it before you bind the GridView as member-variable. Then you don't need to retrieve the same data for each row.

Categories