how to update only child GridView? - c#

here is what I'm doing right now:
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridViewUserScraps_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="MakeComments" runat="server" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btnPost" Text="Comment" runat="server" CommandName="Comment" CommandArgument='<%#Eval("ScrapId")%>' />
<asp:GridView ID="GridView2" runat="server">
<%--this GridView2 showing comments--%>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridViewUserScraps_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridView gv = new GridView();
gv = (GridView)row.FindControl("GridView2");
//getting data to bind child gridview.
gv.DataSource = td;
gv.DataBind();
}
so, on button click of the GridView1 I'm updating database and fetching data at same time, there is no any problem in that. But for this I have to Bind/refresh parent(GridView1) Gridview which quite slow process as there are almost 50 rows. what I'm looking is; I want to update or refresh only GridView2 to be shown added comments.

The GridView1.RowCommand is the right event to handle the button's action.
GridView1.RowCommand += (o, e) =>
{
var row = (e.CommandSource as Button).NamingContainer as GridViewRow;
var makeComments = row.FindControl("MakeComments") as TextBox;
int scrapId = Int32.TryParse((string)e.CommandArgument, out scrapId) ? scrapId : 0;
var gridView2 = row.FindControl("GridView2") as GridView;
... place here the code which the comments
gridView2.DataSource = GetCommentsByScrapId();
gridView2.DataBind();
};
On this event (or others), the parent won't bind, unless you specify it.
One common reason the bind a control is by mistakenly call DataBind() every time when the page loads. To prevent this, it is needed to do the binding on the first request of the page and the proper way is to check if the IsPostBack is false.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GridView1.DataSource = GetUserScraps();
GridView1.DataBind();
}
}

You can refresh only the child gridview without refreshing your parent gridview.
To do it you can do a client side click (ClientClick) to the button and call a jquery function, instead of a server side click.
Then you can update only the items in your child gridview, by calling a web method or http handler class from the particular jquery function via ajax call.
Here your parent grid won't be refreshed since there is no server hit at the button click.
Hope this helps and if you need I will provide sample code for the jquery function.

Try this
foreach(GridViewRow rIndex in GridView1.Rows)
{
GridView gv = new GridView();
gv = (GridView)row.FindControl("GridView2");
//getting data to bind child gridview.
// if you want to get the row key value use GridView1.DataKeys[rIndex.RowIndex].Value
gv.DataSource = td;
gv.DataBind();
}

I would set the commandname of the button then use the gridview's OnRowCommand event
<asp:gridview id="GridView1" runat="server" onrowdatabound="GridViewUserScraps_RowDataBound" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="MakeComments" runat="server" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btnPost" Text="Comment" runat="server" CommandName="UpdateChildGrid" />
<asp:GridView ID="GridView2" runat="server">
<%--this GridView2 showing comments--%>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
Code Behind:
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="UpdateChildGrid")
{
GridViewRow row = (e.CommandSource as Button).NamingContainer as GridViewRow;
GridView child = row.FindControl("GridView2") as GridView;
// update child grid
}
}
Doing this from memory so it may not be exact, but should be close enough to give you an idea of where to go

GridView HTML
<asp:gridview id="GridView1" runat="server" onrowdatabound="GridViewUserScraps_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="MakeComments" runat="server" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btnPost" Text="Comment" runat="server" OnClick="btnPost_Click" />
<asp:GridView ID="GridView2" runat="server">
<%--this GridView2 showing comments--%>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
Code Behind
protected void btnPost(object sender, EventArgs e)
{
//Your code for other operations
//
GridView GridView2 = (GridView)((GridViewRow)((Button)sender).NamingContainer).FindControl("GridView2");
GridView2.DataSource = YourDataBasefetchingFunction();
GridView2.DataBind()
}
Note - Convert the ScrapID DataItem into the DataKey

To Update /refresh only the Child GridView2 in the row where the Update button has been clicked
First of all U need to place the entire GridView1 in Update Panel.
And the child GridView inside another UpdatePanel
Then on the button click U just hav to save ur data and refresh the child grid , in this way only the child grid will be refreshed.
heres a working example.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
SqlConnection conn = new SqlConnection("Password=password;Persist Security Info=True;User ID=uid;Initial Catalog=Northwind;Data Source=servername");
SqlCommand cmd = new SqlCommand("select top 10 * from orders", conn);
cmd.Connection.Open();
var dt = cmd.ExecuteReader();
GridView1.DataSource = dt;
GridView1.DataBind();
cmd.Connection.Close();
cmd.Dispose();
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "UpdateChildGrid")
{
GridViewRow row = (e.CommandSource as Button).NamingContainer as GridViewRow;
GridView child = row.FindControl("GridView2") as GridView;
string id = row.Cells[0].Text;
SqlConnection conn = new SqlConnection("Password=password;Persist Security Info=True;User ID=uid;Initial Catalog=Northwind;Data Source=servername");
SqlCommand cmd = new SqlCommand("select top 5 * from [order Details] where OrderID = " + id, conn);
cmd.Connection.Open();
var dt = cmd.ExecuteReader();
child.DataSource = dt;
child.DataBind();
cmd.Connection.Close();
cmd.Dispose();
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string id = e.Row.Cells[0].Text;
GridView gv = new GridView();
gv = (GridView)e.Row.FindControl("GridView2");
SqlConnection conn = new SqlConnection("Password=password;Persist Security Info=True;User ID=uid;Initial Catalog=Northwind;Data Source=servername");
SqlCommand cmd = new SqlCommand("select top 5 * from [order Details] where OrderID = " + id, conn);
cmd.Connection.Open();
var dt = cmd.ExecuteReader();
gv.DataSource = dt;
gv.DataBind();
cmd.Connection.Close();
cmd.Dispose();
}
}
}
}
And code behind
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<p>
To learn more about ASP.NET visit www.asp.net.
</p>
<p>
You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
</p>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server"
onselectedindexchanged="GridView1_SelectedIndexChanged"
AutoGenerateColumns="False"
onrowcommand="GridView1_RowCommand" onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="OrderID" />
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:TextBox ID="MakeComments" runat="server" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btnPost" ButtonType="Button" Text="Comment" runat="server" CommandName="UpdateChildGrid" />
<asp:GridView ID="GridView2" runat="server">
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>

Related

Cannot search on gridview C# aspnet

I'm implementing a search bar to filter GridView1. I followed this tutorial but when it doesnt work. I want to filter the UserID and show only the specific output match the user input. I clicked on search but nothing work, it just refreshed the page and nothing else.
aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Manager.Master" AutoEventWireup="true" CodeBehind="ExceptionReport.aspx.cs" Inherits="Bracelet.ExceptionReport" %>
<%# Register Assembly="Microsoft.ReportViewer.WebForms" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="col-md-10">
<div class="content-box-large">
<div class="panel-heading">
<div class="panel-title">Admin Log Report</div>
</div>
<asp:TextBox ID="txtSearch" runat="server" />
<asp:Button Text="Search" runat="server"/>
<div class="panel-body">
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="UserID">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID" ReadOnly="True" SortExpression="UserID" />
<asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
<asp:BoundField DataField="UserEmail" HeaderText="UserEmail" SortExpression="UserEmail" />
<asp:BoundField DataField="logtime" HeaderText="logtime" SortExpression="logtime" />
</Columns>
</asp:GridView>
</div>
</div>
<asp:LinqDataSource ID="LinqDataSource2" runat="server" ContextTypeName="Bracelet.BraceletDataContext" EntityTypeName="" TableName="Users">
</asp:LinqDataSource>
<asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="Bracelet.BraceletDataContext" EntityTypeName="" TableName="Users" Where="UserRole == #UserRole">
<WhereParameters>
<asp:Parameter DefaultValue="Admin" Name="UserRole" Type="String" />
</WhereParameters>
</asp:LinqDataSource>
</div>
</asp:Content>
Full code .cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
namespace Bracelet
{
public partial class ExceptionReport : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.BindGrid();
}
}
protected void Search(object sender, EventArgs e)
{
this.BindGrid();
}
private void BindGrid()
{
string constr = ConfigurationManager.ConnectionStrings["BraceletConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT UserID, UserName, UserEmail, logtime FROM [User] WHERE UserID LIKE '%' + #UserID + '%'";
cmd.Connection = con;
cmd.Parameters.AddWithValue("#UserID ", txtSearch.Text.Trim());
DataTable dt = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
this.BindGrid();
}
}
}
Not too bad.
but, there are few errors and issues.
first up, you have search button - but it has no "id" assigned.
You probably should get in the habit of simple drag + drop the button in from the tool box.
So, we now have this for the button and the grid:
<asp:TextBox ID="txtSearch" runat="server" />
<asp:Button ID="cmdSearch" runat="server" Text="Search" />
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="UserID">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID" ReadOnly="True" SortExpression="UserID" />
<asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
<asp:BoundField DataField="UserEmail" HeaderText="UserEmail" SortExpression="UserEmail" />
<asp:BoundField DataField="logtime" HeaderText="logtime" SortExpression="logtime" />
</Columns>
</asp:GridView>
NOTE carefull in above, how we gave the button a "ID"
So, our basic code to load up the grid?
FYI: huge love, hugs, high-5's for checking is-post back!!!
(always, always do that!!!).
So, our code to load things up can thus look like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
this.BindGrid();
}
void BindGrid()
{
string constr = ConfigurationManager.ConnectionStrings["BraceletConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT UserID, UserName, UserEmail, logtime FROM [User]", con))
{
// optional text box filter (blank = all)
if (txtSearch.Text != "")
{
cmd.CommandText += " WHERE UserID LIKE '%' + #UserID + '%'";
cmd.Parameters.Add("#UserID", SqlDbType.Text).Value = txtSearch.Text;
}
con.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
Note how we did not need that data adaptor - not needed.
However, we still not created the code stub for the button click (that's why your code is not working - you did not give your button a "id"
So, in the designer - double click on the button. That will create the "event" for you, and jump to the code editor, and we have this:
protected void cmdSearch_Click(object sender, EventArgs e)
{
this.BindGrid();
}
so, in general - don't type in the "event" stubs for a button - double click on the button - it will create + wire it up for you.
Note close, if I flip back to mark-up, the button has become this:
<asp:Button ID="cmdSearch" runat="server" Text="Search" OnClick="cmdSearch_Click" />

ASP.NET control in GridView not found to exist in code behind

I have a DropDownList that I would like to populate with column values from a DataBase. However, when I try to bind the DropDownList in code behind, the IDE keeps telling me:
"The name 'EqpCatDDL' does not exist in the current context"
I am not sure what is going on since I referred to the control by its ID. The following is the code:
aspx:
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false"
>
<Columns>
<asp:BoundField DataField="S/N" HeaderText="S/N" />
<asp:TemplateField HeaderText="Item Name">
<ItemTemplate>
<asp:DropDownList ID="EqpCatDDL" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:DropDownList ID="DescripDDL" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Remarks">
<ItemTemplate>
<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" onclick="ButtonAdd_Click" runat="server" Text="Add New Row" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
c#:
public void Populate1()
{
string connString = ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString;
SqlConnection connection = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand("SELECT EqpCateID, EqpCat FROM EqpCategory", connection);
cmd.Connection.Open();
SqlDataReader ddlValues;
ddlValues = cmd.ExecuteReader();
EqpCatDDL.DataSource = ddlValues;
EqpCatDDL.DataValueField = "EqpCateID";
EqpCatDDL.DataTextField = "EqpCat";
EqpCatDDL.DataBind();
cmd.Connection.Close();
cmd.Connection.Dispose();
}
protected void Page_Load(object sender, EventArgs e)
{
Populate1();
}
The IDE can't find the EqpCatDDL control.
I am using the following: Visual Studio 2010, Microsoft SQL Server Management Studio 2008
I am working with a Visual Studio website
Use this code to bound data to dropdown without using RowDataBound.
Create a function that'll bind the Data to dropdown as follow and call it in Page_Load event
Public void fill_gridView_dropDown()
{
// your connection and query to retrieve dropdown data will go here
// this loop will go through all row in GridView
foreach(GridViewRow row in your_gridView_Name.Rows) {
DropDownList dropDown = (DropDownList)row.FindControl("dropDownList_id");
dropDown.DataSource = dataSource;
dropDown.DataValueField = "ValueField";
dropDown.DataTextField = "TextField";
dropDown.DataBind();
}
}
Please note that you have to bind GridView first, and then you have to bind your dropdown
your dropdown is in gridview so you can try with this code
protected void Gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var ddl = (DropDownList)e.Row.FindControl("EqpCatDDL'");
SqlCommand cmd = new SqlCommand("SELECT EqpCateID, EqpCat FROM EqpCategory", connection);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
EqpCatDDL.DataSource = ds;
EqpCatDDL.DataValueField = "EqpCateID";
EqpCatDDL.DataTextField = "EqpCat";
EqpCatDDL.DataBind();
}
}
You can't directly populate GridView's dropdownlist like this. You need to set datasource of GridView first i.e.
GridView1.DataSource = DataSource
And if you would like to access dropdownlist of this gridview, you can use RowDataBound event handler of GridView i.e.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Checking whether the Row is Data Row
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Finding the Dropdown control.
Control ctrl = e.Row.FindControl("EqpCatDDL");
if (ctrl != null)
{
DropDownList dd = ctrl as DropDownList;
List lst = new List();
dd.DataSource = lst;
dd.DataBind();
}
}
}

Populates GridView2 based on selected row from GridView1

I have 2 gridview on my page: on GridView1 I have a column with select link, Id and Name which looks like this:
Select | Id | Name
select | 101 | Jack
select | 102 | Cath
Now, what I am trying to do is let's say, I clicked the select from the first row which is Jack, now my GridView2 will display the products ordered by Jack which looks like this:
Id | ProductID
101 | 111
101 | 222
101 | 333
and if Cath whom I selected, GridView2 will change the display products which ordered by Cath:
Id | productID
102 | 111
102 | 333
102 | 555
In short, I am trying to populate GridView2 based on the selected row from the GridView1. I am using asp.net with C#.
When you are selecting the row in 1st grid then in selectIndexChanged event of your grid take the value of the primary key ID and store in hiddenField
If you have used Datakey then use
SelectedDatakey
take the value of SelectedDatakey and store in hiddenfield
protected void CustomersGridView_SelectedIndexChanged(Object sender, EventArgs e)
{
hiddenfield1.value = CustomersGridView.SelectedDataKey.Value;
}
Now In your query to fill the 2nd grid pass the 1st grid's key value which you have stored in hiddenfield in where condition and populate the second grid according to your query result
This is my sample code......
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<Data> DataList = new List<Data>() { new Data { id = 1, id2 = 2 }, new Data { id = 3, id2 = 4 } };
GridView1.DataSource = DataList;
GridView1.DataBind();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
GridViewRow row = (GridViewRow ) btn.NamingContainer;
Label slNoLabel = (Label) row.FindControl("slNoLabel");
// function to get data based on label vlue
GridView2.DataSource=GetData(slNoLabel.Text);
GridView2.DataBind();
}
DataTable GetData(string value)
{
DataTable tbl = new DataTable ();
// Calling DB
return tbl;
}
}
public class Data
{
public int id { get; set; }
public int id2 { get; set; }
}
and in the UI
<div>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="Button1" runat="server" CausesValidation="False" CommandName="Select" OnClick="Button1_Click" Text="Select" />
<asp:Button ID="Button2" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:GridView ID="GridView2" runat="server"></asp:GridView>
</div>
You can add an onClick method on the link button you added for "Select".
<asp:GridView ID="Gridview1" runat="server"
AllowPaging="true" PageSize="15" RowStyle-Wrap="true" EmptyDataRowStyle-ForeColor="Red"
AutoGenerateColumns="false" GridLines="None">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:LinkButton ID ="li_Select" runat="server" Text="Select" OnClick="li_Select_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label runat="server" ID="lbl_ID" Text='<%#Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label runat="server" ID="lbl_Name" Text='<%#Eval("Name") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now Filter the data or fetch the data from the database on the basis of clicked row ID.
protected void li_Select_Click(object sender, EventArgs e)
{
LinkButton lnkbtn = (LinkButton)sender;
GridViewRow row = (GridViewRow)lnkbtn.NamingContainer;
Label lbl_ID = (Label)row.FindControl("lbl_ID");
// You can fetch the data from the database on the basis of selected User ID .
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Product_ID");
for (int i = 100; i <= 110; i++)
{
DataRow dr = dt.NewRow();
dr["ID"] = i;
dr["Product_ID"] = "P_" + i;
dt.Rows.Add(dr);
}
// In this method you pass the id of the user, and datatable fetched from the database of all products. or you can pass the id in the storedprocedure to get data of selected user only and then bind it here .
GetData(lbl_ID.Text,dt);
}
protected void GetData(string ID, DataTable dt)
{
DataView dv = dt.DefaultView;
dv.RowFilter = "ID=" + ID;
Gridview2.DataSource = dv;
Gridview2.DataBind();
}
The best way of doing this in my opinion is to use UpdatePanel to bind the second grid, using this you will have an advantage, no postback (it is postback actually, but the user wont notice it..)...
And if you don't use the UpdatePanel, then there is no way you can see the data after binding it in the postback (unless you are doing it through Javascript, which is a hassle)...Here is the sample code for achieving it:
ASPX Page:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="GridView2" runat="server" >
<Columns>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:LinkButton ID="asd" Text='Select' runat="server" OnClick="link_click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Code Behind:
protected override void PageLoad(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = getDataSource();
GridView1.DataBind();
}
}
private DataTable getDataSource()
{
SqlConnection conn = new SqlConnection("Server=192.168.1.1;DATABASE=dummy;UID=****;PWD=*****;"); //Example connString
SqlCommand comm = new SqlCommand("SELECT * FROM Table1", conn);
SqlDataAdapter ad = new SqlDataAdapter(comm);
DataTable ta = new DataTable();
ad.Fill(ta);
return ta;
}
protected void button_click(object sender, EventArgs e)
{
LinkButton asd = (LinkButton)sender;
GridViewRow row = (GridViewRow)asd.NamingContainer; //Gets the selected Row
string user_id = row.Cells[2].Text; //Use this to get any value you want.
//Can now use the user_name to get the data for the grid 2, and update the panel
GridView2.DataSource = getDataSource2(user_id);
GridView2.DataBind();
UpdatePanel1.Update();
}
private DataTable getDataSource2(string user_id)
{
string sql = "SELECT * FROM TABLE2 WHERE user_id = #user_id";
SqlConnection conn = new SqlConnection("Server=sqlserver\\sql2008;DATABASE=esm80;UID=sa;PWD=sa;"); //Example connString
SqlCommand comm = new SqlCommand();
comm.CommandText = sql;
comm.Parameters.AddWithValue("#name", user_id);
comm.Connection = conn;
SqlDataAdapter ad = new SqlDataAdapter(comm);
DataTable ta = new DataTable();
ad.Fill(ta);
return ta;
}
Now the explaination, the UpdatePanel of GridView2 is there to update the gridView2 once the data is binded to it (this will show the newly binded data). The UpdatePanel of GridView1 is there to prevent the postback, from the link button.
Hope this answers your question.

How to highlight a selected row in a gridview?

I am adding a dropdown to gridview using template field as:
<asp:TemplateField HeaderText="Change Color">
<ItemTemplate>
<asp:DropDownList ID="dropdownid" DataSourceID="sqldatasource_id" DataTextField="username"
BackColor="GrayText" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" AppendDataBoundItems="True" runat="server" AutoPostBack="True">
<asp:ListItem Text="--Select One--" Value="" Selected="True" />
</asp:DropDownList>
SqlDataSource is:
<asp:SqlDataSource ID="sqldatasource_id" runat="server" ConnectionString="<%$ ConnectionStrings:crudconnection %>"
SelectCommand="SELECT [username] FROM [crudtable]"></asp:SqlDataSource>
Indexchange-Event is as :
protected void GridView1_SelectedIndexChanged(object sender,EventArgs e)
{
}
I want to highlight a row when any value from the corresponding dropdownlist is selected.
How can i do it?
Thanks in advance.
i tried it:
GridView1.Rows[GridView1.SelectedIndex].BackColor = Color.Red;
But still it is giving a exception as follow when-ever i select any value from any dropdownlist.
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I am getting index number of selected row as already mentioned.can't i increment it from there and can use back-color property too?
Can you give this a try:
GridView1.Rows[GridView1.SelectedIndex].BackColor = Color.Red inside your GridView1_SelectedIndexChanged?
It should set the background color of the selected row to a red color
Try GridView_SelectedIndexChanging(). Here is how:
protected void GridView1_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
//This is current row. Set it to default color
GridView1.SelectedRow.BackColor = System.Drawing.Color.White;
//This is selected row. Set it to color you wish
GridView1.Rows[e.NewSelectedIndex].BackColor = System.Drawing.Color.Black;
}
Its working.I made changes like below.
int abc=row.rowindex+3;
GridView1.Rows[abc].BackColor = Color.Yellow;
Thanks for support.
function ChangeRowColor(row) {
row = parseInt(row) + 1;
if (previousRow == row)
return; //do nothing
else if (previousRow != null) {
document.getElementById("MainContent_gvSimulationManager").rows[previousRow].style.backgroundColor = previouscolor;
}
previouscolor = document.getElementById("MainContent_gvSimulationManager").rows[row].style.backgroundColor;
document.getElementById("MainContent_gvSimulationManager").rows[row].style.backgroundColor = "#888888";
previousRow = row;
//Disable and enable Session
var simulationStatus = document.getElementById("MainContent_gvSimulationManager").rows[row].cells[3].innerText;
EnableAndDisable(simulationStatus);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"
OnRowDataBound="GridView1_RowDataBound" OnSelectedIndexChanged = "OnSelectedIndexChanged">
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="pub_id" HeaderText="pub_id" />
<asp:BoundField DataField="pub_name" HeaderText="pub_name" />
<asp:BoundField DataField="city" HeaderText="city" />
<asp:BoundField DataField="state" HeaderText="state" />
<asp:BoundField DataField="country" HeaderText="country" />
<asp:ButtonField Text="Click" CommandName="Select" ItemStyle-Width="30" />
</Columns>
</asp:GridView>
<br />
<asp:Label ID="msg" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SqlDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
int i = 0;
string sql = null;
string connetionString = "Data Source=.;Initial Catalog=pubs;User ID=sa;Password=*****";
sql = "select * from publishers";
SqlConnection connection = new SqlConnection(connetionString);
connection.Open();
SqlCommand command = new SqlCommand(sql, connection);
adapter.SelectCommand = command;
adapter.Fill(ds);
adapter.Dispose();
command.Dispose();
connection.Close();
GridView1.DataSource = ds.Tables[0];
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.backgroundColor='aquamarine';";
e.Row.Attributes["onmouseout"] = "this.style.backgroundColor='white';";
e.Row.ToolTip = "Click last column for selecting this row.";
}
}
protected void OnSelectedIndexChanged(object sender, EventArgs e)
{
string pName = GridView1.SelectedRow.Cells[1].Text;
grdCList.SelectedRow.Cells[3].ForeColor = System.Drawing.Color.Red;
}

In a GridView, how to add multiple commands to one item template?

I stripped this example to make it simple. I have a gridview with a template field. The template field contains two buttons and a label (They must be in the same template field). I want the first button to set the label text to "Win", and the other button to set the label text to "fail". The onrowcommand doesnt seem to be triggered by buttons in a template field. How can I accomplish this?
My gridview code is below:
<asp:GridView ID="GridView1" runat="server" EnableModelValidation="True" AutoGenerateColumns="False"
OnRowCommand="Gridview1_RowCommand">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="btnWin" runat="server" CommandName="Win" Text="Win" />
<asp:Button ID="btnFail" runat="server" CommandName="Fail" Text="Fail" />
<asp:Label ID="lblStatus" runat="server" Text='<%# Bind("text") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and my code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataTable myTable = new DataTable();
myTable.Columns.Add("text", typeof(string));
myTable.Rows.Add("First Entry");
myTable.Rows.Add("Second Entry");
GridView1.DataSource = myTable;
GridView1.DataBind();
}
public void Gridview1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
//set lblStatus.text to "Win", or "Fail"
}
Thanks in advance!
Here you go...
public void Gridview1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
lblStatus.Text = e.CommandName;
}
I see that there is more to this question than is answered here, bear with me. One way would be to delegate the OnCommand event of each button to its designated event handler, as follows:
<div>
<asp:GridView ID="MyGridView" runat="server" EnableModelValidation="true" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="MyWinButton" runat="server" OnCommand="MyWinButton_OnCommand" CommandName="Win" Text="Win" />
<asp:Label ID="MyStatusLabel" runat="server" Text='<%# Bind("text") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
public void MyWinButton_OnCommand(Object sender, CommandEventArgs e)
{
var label = ((Button)sender).Parent.FindControl("MyStatusLabel") as Label;
label.Text = e.CommandName;
}
Also, as Alison suggests, you won't see the desired output of this unless you use !IsPostBack in Page_Load. Furthermore, on doing so this does in fact enable you to use the one row command event handler as initially suggested, albeit with a slight change in the label retrieval:
public void MyGridView_OnRowCommand(Object sender, GridViewCommandEventArgs e)
{
var label = ((Button)e.CommandSource).Parent.FindControl("MyStatusLabel") as Label;
label.Text = e.CommandName;
}
Are you using a MasterPage with ViewState turned off? Buttons in a template field with ViewState set to false will not fire.
Also, you should change your Page_Load to NOT rebind on postback"
protected void Page_Load(object sender, EventArgs e)
{
if (!page.IsPostBack) {
DataTable myTable = new DataTable();
myTable.Columns.Add("text", typeof(string));
myTable.Rows.Add("First Entry");
myTable.Rows.Add("Second Entry");
GridView1.DataSource = myTable;
GridView1.DataBind();
}
}
The rebinding may be interfering.

Categories

Resources