How to get a specific data in gridview using c#? - c#

I was wondering how to retrieve a specific data from gridview. My database consists of columns like id, type and name. Lets say the contents of my gridview is like this example below:
Id Type Name
1 Guitar Ibanez
2 Guitar Gibson
What i want to happen is to get the value under Name, Lets say "Ibanez". I was able to retrieve the value for Id using datakeys but I can't figure out how to get the value of Name in Gridview. I included code below to better understand what i mean.
protected void GuitarBrandsGridViewBtn_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gridrow = btn.NamingContainer as GridViewRow;
int id = Convert.ToInt32(GuitarBrandsGridView.DataKeys[gridrow.RowIndex].Value.ToString());
con.Open();
cmd.CommandText = "DELETE FROM [guitarBrands] WHERE id=" + id;
cmd.Connection = con;
int a = cmd.ExecuteNonQuery();
con.Close();
if (a > 0)
{
bindgridviewguitarbrands();
}
System.IO.File.Delete(#"C:\Users\User1\Documents\Visual Studio 2015\WebSites\MusicStore\Pages\GuitarItemsIbanezDetails" + id + ".aspx");
System.IO.File.Delete(#"C:\Users\User1\Documents\Visual Studio 2015\WebSites\MusicStore\Pages\GuitarItemsIbanezDetails" + id + ".aspx.cs");
}

You can access specific columns like this
GuitarBrandsGridView.Rows[gridrow.RowIndex].Cells[1].Text;

you can use template field in the grid view instead of bound field like this :
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("ColumnNameOfYourDatasourceForName") %>' />
</ItemTemplate>
</asp:TemplateField>
and then get the label and its text in code behind from following code :
protected void GuitarBrandsGridViewBtn_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gridrow = btn.NamingContainer as GridViewRow;
Label lblName = gridrow.FindControl("lblName");
string name = lblName.Text;
}

Related

Attaching a click event onto an image within a grid view

I am having trouble attaching a click event onto an image that I have stored within a grid view. Basically it is a delete button that will allow the user to delete a specific row depending on where the button is. I have the code in c# ready for it, however, I cannot seem to attach a click event to it.
This is the markup code of the button
<asp:TemplateField HeaderText="Remove" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="imgbDeleteP" runat="server" BORDER="0" CausesValidation="false" ImageUrl="~/img/Del.png" Height="25px" ImageAlign="Middle"
onClick ="gv_Quals_RowCommand" CommandArgument="<%#Container.DataItemIndex%>" CommandName="Remove" />
</ItemTemplate>
onClick ="gv_Quals_RowCommand"
Here is the code in c# for the click event
protected void gv_Quals_RowCommand(object sender, GridViewCommandEventArgs e)
{
if ((e.CommandName == "Remove"))
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gv_Quals.Rows[index];
DataTable dtCurrentTable = (DataTable)Session["CurrentTable"];
dtCurrentTable.Rows[index].Delete();
if ((dtCurrentTable.Rows.Count < 0))
{
}
else if ((row.Cells[0].Text != "*New*"))
{
int appId = 5000;
//int appId = 1;
string insProg = ("delete from projectunitassignment where UnitId =" + int.Parse(row.Cells[0].Text));
SqlCommand cmd = new SqlCommand(insProg, conn);
cmd.Connection.Close();
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
RebindCat(appId);
}
}
}
This is the compilation error that I keep getting
CS0123: No overload for 'gv_Quals_RowCommand' matches delegate 'ImageClickEventHandler'
I cannot set the click event through the properties as it is stored within the grid view so I cannot access it through there. Also the click event does not run as I have tested with debugging
The problem is with GridViewCommandEventArgs should be just EventArgs
public void imgbDeleteP_Click(object sender, EventArgs e)
Edit:
I see that in your code you use the Command Argument, so if you want to use that you should see this post
Basically use onCommand instead of onClick or cast the sender to button to get the command argument, something like:
var argument = ((ImageButton)sender).CommandArgument;
Did you try to associate the click event for that grid during page load ?
I think that is because of GridViewCommandEventArgs which commonly used for RowCommand , change it to EventArgs, so that event should be something like this:
protected void gv_Quals_RowCommand(object sender, EventArgs e)
{
ImageButton btn = (ImageButton)sender;
string cmName= btn.CommandName;
string cmArgument= btn.CommandArgument;
if ((cmName == "Remove"))
{
.....
}
}
or to get row index:
GridViewRow gvRow = (GridViewRow)(sender as Control).Parent.Parent;
int index = gvRow.RowIndex;
The first parent is the GridView Cell and the second parent of the GridView Cell is the GridView Row.

Gridview on Linkbutton click, Pass complete GridRow information to the next page? What are best ways to do this?

I have Gridview that has 6 other BoundField Columns and one Linkbutton column.
I want to pass all the Row information to the next page when users click on LinkButton.
What are the best ways to do this?
If we pass it as QueryString, it is going to be Too long.
Thanks
You can use the LinkButton Column itself to your advantage.
The idea is to send the RowIndex of the GridViewRow in PostBackUrl property of LinkButton as a QueryString Parameter.
Use the Container.DataItemIndex which represents the Index of the Row.
At the Next/Destination page , get the RowIndex from QueryString to get the GridViewRow and then read the Column values.
Step 1.) The markup corresponding to LinkButton should be as below:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="Send Details"
PostBackUrl='<%# "~/NextPage.aspx?RowIndex=" +
Container.DataItemIndex %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Step 2.) In the Page Load event of NextPage.aspx, get first the GridViewRow where LinkButton was clicked and then read the row values
Note that using the PostBackUrl property in essence makes a cross page postback and therefore you can use the property Page.PreviousPage
protected void Page_Load(object sender, EventArgs e)
{
if (this.Page.PreviousPage != null)
{
int rowIndex = int.Parse(Request.QueryString["RowIndex"]);
GridView GridView1 = (GridView)this.Page.PreviousPage.FindControl("GridView1");
GridViewRow row = GridView1.Rows[rowIndex];
//Since you use Bound Fields, use row.Cells[] to read values
String Column_One_Value = row.Cells[0].Text;
String Column_Two_Value = row.Cells[1].Text;
}
}
Too long is subjective, anyways, if you don't want to use QueryString you can use Session Variables, Session vars are kept across the web site
protected void gvUsers_PageIndexChanging(object sender, EventArgs e)
{
Session["TheSelectedRow"] = ((Control)sender).Parent as GridViewRow;
// Your code to redirect
}
or you can wrap them in Properties, to work better and avoid casting every time in different lines and spelling mistakes
public GridViewRow TheSelectedRow
{
get { return Session["TheSelectedRow"] == null ? null : Session["TheSelectedRow"] as GridViewRow; }
set { Session["TheSelectedRow"] = value; }
}
and then in your click event this
protected void gvUsers_PageIndexChanging(object sender, EventArgs e)
{
TheSelectedRow = ((Control)sender).Parent as GridViewRow;
// Your code to redirect
}

Trouble grabbing Row Number from GridView

I have the following GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="SysInvoiceID" HeaderText="SysInvoiceID" ReadOnly="True" SortExpression="SysInvoiceID" />
<asp:BoundField DataField="BillMonth" HeaderText="BillMonth" SortExpression="BillMonth" />
<asp:BoundField DataField="InvoiceDate" HeaderText="InvoiceDate" ReadOnly="True" SortExpression="InvoiceDate" />
<asp:BoundField DataField="InvoiceNumber" HeaderText="InvoiceNumber" SortExpression="InvoiceNumber" />
<asp:BoundField DataField="Net" HeaderText="Net" SortExpression="Net" />
<asp:BoundField DataField="VAT" HeaderText="VAT" SortExpression="VAT" />
<asp:BoundField DataField="Gross" HeaderText="Gross" SortExpression="Gross" />
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</Columns>
</asp:GridView>
Here is the code behind the page:
public partial class PagingTest01 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if (e.CommandName == "ViewInvoice")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection.
GridViewRow row = GridView1.Rows[index];
// Now you have access to the gridviewrow.
ViewButton_Click(row);
}
}
protected void ViewButton_Click(GridViewRow row)
{
byte[] FileImage = GetImageData(0,row);
if (FileImage != null)
{
base.Response.Clear();
base.Response.Buffer = true;
base.Response.ContentType = "Application/x-pdf";
base.Response.ContentEncoding = Encoding.Default;
string attachment = string.Format("attachment;filename=\"Invoice_{0}.pdf\"", "Customer1");
base.Response.AddHeader("content-disposition", attachment);
base.Response.BinaryWrite(FileImage);
base.Response.Flush();
base.Response.Close();
base.Response.End();
}
}
public byte[] GetImageData(int sysInvoiceID, GridViewRow row)
{
string strUserID = CommonCode.GetCurrentUserID().ToString();
string strCustomerID = CommonCode.GetCurrentCustomerID().ToString();
byte[] numArray;
string strConnectionString = "Data Source=TESTSERV;Initial Catalog=DB_Invoices;Persist Security Info=True";
SqlConnection connection = new SqlConnection(strConnectionString);
SqlCommand command = new SqlCommand("select FileImage from DB_Invoices.dbo.Bills WHERE (FileType = 'PDF' AND SysInvoiceID = #ID)", connection);
command.Parameters.AddWithValue("#ID", GridView1.Rows[row].Cells[0].Text);
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
try
{
connection.Open();
da.Fill(ds);
DataRow item = ds.Tables[0].Rows[0];
byte[] item1 = (byte[])item["FileImage"];
ds.Tables.Clear();
numArray = item1;
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
}
return numArray;
}
}
So basically I have a GridView with a lot of rows, each one with a 'View' Buttonfield next to it. When 'View' is clicked, I attempted to make use of GridView1_RowCommand which should hopefully grab the row clicked before passing it onto ViewButton_Click. This will then call GetImageData and pass the row number onto this line:
command.Parameters.AddWithValue("#ID", GridView1.Rows[row].Cells[0].Text);
Cell 0 is the SysInvoiceID column, so if the correct row is passed, #ID will be assigned a SysInvoiceID.
'Row' however doesn't seem to be a valid argument, though I can't think why not... Unless I have to explicitly convert it into a int? Any help would be really appreciated! Thanks.
I have just commented this as side-note but maybe it's your issue because you mention that "it doesn't seem to be a valid argument, though I can't think why not... Unless I have to explicitly convert it into a int".
If ID is an int you should use int.Parse(celltext), othwerwise the database gets the wrong type since AddWithValue needs to infer the type from the value.
So use:
command.Parameters.AddWithValue("#ID", int.Parse(GridView1.Rows[row].Cells[0].Text));
Apart from that, you haven't added the event handler GridView1_RowCommand.
<asp:GridView ID="GridView1" OnRowCommand="GridView1_RowCommand" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
....
and you are also not setting the CommandArgument to the index of the row. I would use a different approach anyway if you need the row-index. Use a templatefield and a control, for example a Button. Then use it's NamingContainer property to get the reference to the 'GridViewRow`, here is an example: Get Row Index on Asp.net Rowcommand event
use this:
int index = ((GridViewRow)((WebControl)sender)).RowIndex;
in place of
int index = Convert.ToInt32(e.CommandArgument);

Display data in Nested repeater control & how to pass value parentID from Parent Repeater to Child Repeater using asp.net

I have to display photo gallery as show in the image. I store information for photo gallery in 4 different tables. i need to show on main page CategoryName and Albums along with their respected Icon and link them to a AlbumCategoryPage.aspx.
In order to achieve this i am using nested repeater control.
Parent Repeater will show Category Image (as show in red color) and then show Top 4 albums in the same category and so in.
So far i have done it like this
<asp:Repeater ID="rptAlbumCategory" runat="server" OnItemDataBound="rptAlbumCategory_ItemBound">
<ItemTemplate>
<!-- Repeated data -->
<div class="AlbumRowWrapper">
<div id="dAlbumCategory" class="AlbumCategoryIcon">
<asp:Image ID="Image1" ImageUrl='<%# getImagePath(Eval("CategoryImage")) %>' runat="server" />
</div>
</div>
<asp:Repeater ID="rptAlbums" runat="server" >
<ItemTemplate>
<!-- Nested repeated data -->
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Code Behind
On Page Load
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{ //Get Gallery
DataSet dsAlbumCat = new DataSet();
string strSql = "SELECT * FROM AlbumCategory)";
dsAlbumCat = DataProvider.Connect_Select(strSql);
rptAlbumCategory.DataSource = dsAlbumCat;
rptAlbumCategory.DataBind();
}
}
protected void rptAlbumCategory_ItemBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
Repeater childRepeater = (Repeater)e.Item.FindControl("rptAlbumCategory");
// childRepeater.DataSource = getAlbums();
// childRepeater.DataBind();
}
}
protected void getAlbums()
{
DataSet dsAlbums = new DataSet();
string strSql = "SELECT * FROM AlbumName WHERE CategoryID = " + CategoryID + ")";
dsAlbums = DataProvider.Connect_Select(strSql);
rptAlbums.DataSource = dsAlbums;
rptAlbums.DataBind();
}
protected String getImagePath(object img)
{
string url;
url = "~/Images/gallery/" + img;
return url;
}
With this code i am able to get the following result.
I am not sure how i can pass the CategoryID from the parent repeater to Child repeater so that it will show me the related albums.
I am using nested repeater for first time & find it confusing as i cant find complete example related to my scenario
Table structure
TABLE AlbumCategory
CategoryID
CategoryName
CategoryImageIcon
CategoryVisible
LanguageID
TABLE AlbumName
AlbumID
AlbumName
AlbumDescription
AlbumImageIcon
CategoryID
LanguageID
I would appreciate help in this regard even best approach to accomplish the same design as show in first image
Try this
Dim ds As DataSet = getCategoriesAndName()
ds.Relations.Add("relation_category", ds.Tables(0).Columns("CategoryID"), ds.Tables(1).Columns("CategoryID"))
rptAlbumCategory.DataSource = ds
rptAlbumCategory.DataBind()
getCategoriesAndName() will return dataset having two datatables(categories and names). Then on
Protected Sub rptAlbumCategory_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptAlbumCategory.ItemDataBound
Dim rptrAlbums As Repeater = TryCast(e.Item.FindControl("rptrAlbums"), Repeater)
rptrAlbums.DataSource = TryCast(e.Item.DataItem, DataRowView).CreateChildView("relation_category")
' Bind the child repeater
rptrAlbums.DataBind()
End Sub
I think this is easier :-)

accessing data of a GridView on button click

I am having a gridview with some columns and a template field column that contains a button and I want to call a procedure on button click, however I want to pass a value of a column to the procedure but I am getting an error, here is the action listener of the button: (column name in the gridview is team_ID)
error: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
error line: int team_ID = Convert.ToInt32(Eval("team_ID"));
protected void Button1_Click(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["MyDbConn"].ToString();
SqlConnection conn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand("join_team", conn);
cmd.CommandType = CommandType.StoredProcedure;
int team_ID = Convert.ToInt32(Eval("team_ID"));
string email = Session["email"].ToString();
cmd.Parameters.Add(new SqlParameter("#team_ID", team_ID));
cmd.Parameters.Add(new SqlParameter("#myemail", email));
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
First, to handle a button what was clicked in an TemplateField, you'll want to subscribe to the RowCommand method:
<asp:GridView runat="server" ID="gv" OnRowCommand="yourMethod">
You can have multiple buttons in your grid and surmise which caused the click with the CommandName property. The code below shows this, as well as how to get the row of the button that was clicked, and retrieve other controls from that row so you can get their values.
<asp:TemplateField>
<ItemTemplate>
<asp:Button CommandName="yourButtonName" runat="server" />
Code Behind
protected void yourMethod(object sender, GridViewCommandEventArgs e) {
if (e.CommandName == "yourButtonName") {
GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
TextBox someTextBox = row.FindControl("tb") as TextBox;
string textValue = someTextBox.Text;
}
}

Categories