grid_selectedindexchanged problem - c#

//code in aspx file:
<html>
<body>
<form>
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="False"
onselectedindexchanged="grid_SelectedIndexChanged" >
<Columns>
<asp:BoundField DataField="RollID" HeaderText="RollID" />
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:ButtonField CommandName="Select" Text="Select" />
</Columns>
</asp:GridView>
</div><br />
<asp:label ID="Label" runat="server" text=""></asp:label>
</form>
</body>
</html>
//code behind file:
protected void grid_SelectedIndexChanged(object sender, GridViewRowEventArgs e)
{
RowIndex = grid.SelectedIndex;
GridViewRow row = grid.Rows[RowIndex];
string a = row.Cells[4].Text;
Label.Text = "You selected " + a + ".";
}
!!! The question is,though iam able to print the data in the grid view form,but when i select a row,i could not print out the message"You selected..etc.." with the use of "Label" server control.
"could any1 plz sort m out dis issue"...

Don't use the SelectedIndexChanged event. Instead, use the RowCommand event:
protected void grid_RowCommand(object sender, GridViewCommandEventArgs e) {
if (e.CommandName == "Select") {
int RowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow row = grid.Rows[RowIndex];
string a = row.Cells[4].Text;
Label.Text = "You selected " + a + ".";
}
}
MSDN Link: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand.aspx

How are you selecting a row? You may want to set this attribute on the gridview to allow selection to even take place (that the gridview is aware of) by allowing the control to generate a button:
AutoGenerateSelectButton="True"
You can see more information about this here. Of course, this isn't the only way to create a command button, but you'll have to followup if it won't suit your purposes.

Related

How to Populate Textbox after GridView row clicked in C#

I have a GridView:
<asp:GridView ID="gridSearchResults" AutoGenerateColumns="false" DataKeyNames="uid" runat="server"
AllowSorting="true" AutoGenerateSelectButton="true" CssClass="table table-striped table-bordered"
OnRowDataBound="gridSearchResults_RowDataBound"
OnSelectedIndexChanged="gridSearchResults_UserSelected">
<Columns>
<asp:BoundField DataField="uid" HeaderText="UID" SortExpression="uid" ItemStyle-Width="30%"/>
<asp:BoundField DataField="givenName" HeaderText="First Name" SortExpression="givenName" ItemStyle-Width="35%" />
<asp:BoundField DataField="sn" HeaderText="Last Name" SortExpression="sn" ItemStyle-Width="35%" />
</Columns>
</asp:GridView>
With `AutoGenerateSelectButton="true" a "select" button appears in every row. I can click on this and fire:
`protected void gridSearchResults_UserSelected(object sender, EventArgs e) {
// Get the user's ID from the selected row
idNumber.Text = gridSearchResults.SelectedRow.Cells[1].Text;
firstName.Text = gridSearchResults.SelectedRow.Cells[2].Text;
lastName.Text = gridSearchResults.SelectedRow.Cells[3].Text;
}
which works. However, I would like to remove the "select" button and be able to press anywhere in the row to populate the TextBoxes.
This is the code for gridSearchResults_RowDataBound, which should handle the row click:
protected void gridSearchResults_RowDataBound(object objSender, GridViewRowEventArgs gridViewRowEventArgs) {
if (gridViewRowEventArgs.Row.RowType == DataControlRowType.DataRow) {
// Setup click handler and cursor
//gridViewRowEventArgs.Row.Attributes["onclick"] = DONT KNOW WHAT TO ADD HERE
gridViewRowEventArgs.Row.Attributes["style"] = "cursor:pointer";
// Implement row mouseover and mouseout
gridViewRowEventArgs.Row.Attributes.Add("onmouseover", "this.originalStyle=this.style.backgroundColor; this.style.backgroundColor='#B3E5FC';");
gridViewRowEventArgs.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=this.originalStyle;");
}
}
I have seen something like e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(grdSearchResults, "Select$" + e.Row.RowIndex); but I'm not sure how to mix the two.
Thanks in advance for any help!
The answer can be found here; https://www.aspsnippets.com/Articles/Selecting-GridView-Row-by-clicking-anywhere-on-the-Row.aspx
For my solution I needed to modify a couple of things. In gridSearchResults_RowDataBound I need to add:
gridViewRowEventArgs.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(gridSearchResults, "Select$" + gridViewRowEventArgs.Row.RowIndex);
In gridSearchResults_UserSelected I needed to update the Cell indices.

Gridview column linkbutton change the value according to data

I am trying to complete a simple task;
a gridview column gets an integer data if integer is equals to zero print "active" and set the commandname of the linkbutton to active else set linkbutton text and command value to inactive.
here is what I have so far
<Columns>
<asp:BoundField HeaderText = "User Name" DataField="UserName"
HeaderStyle-Width="16%" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField HeaderText = "Role" DataField="RoleNAME"
HeaderStyle-Width="14%" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField HeaderText = "Group" DataField="GroupName"
HeaderStyle-Width="12%" ItemStyle-HorizontalAlign="Center" />
<asp:ButtonField ButtonType="link" CommandName = "Active"
HeaderText="Status" Text="Active"
HeaderStyle-Width="10%" ItemStyle-HorizontalAlign="Center" />
<asp:ButtonField ButtonType="link" CommandName = "Edit"
HeaderText="" Text="Edit/View"
HeaderStyle-Width="10%" ItemStyle-HorizontalAlign="Center" />
</Columns>
codebehind
protected void grdMyQueue_RowdataBound(object sender, GridViewRowEventArgs e)
{
// In template column,
if (e.Row.RowType == DataControlRowType.DataRow)
{
var obj = (User)e.Row.DataItem;
if (obj.isDisabled == 0)
{
LinkButton linkButton = new LinkButton();
linkButton.Text = "Active";
linkButton.Enabled = true;
linkButton.CommandName = "Active";
//linkButton.CommandArgument = e.Row. //this might be causing the problem
e.Row.Cells[3].Controls.Clear();
e.Row.Cells[3].Controls.Add(linkButton);
}
else
{
LinkButton linkButton = new LinkButton();
linkButton.Text = "InActive";
linkButton.Enabled = true;
linkButton.CommandName = "InActive";
e.Row.Cells[3].Controls.Add(linkButton);
}
}
}
However when I Click the active linkbutton on the cell I get an error at onrowcommand function
protected void OnRowCommand(object sender, GridViewCommandEventArgs e)
{
int index = Convert.ToInt32(e.CommandArgument); // this is the error line
GridViewRow gvRow = userManager.Rows[index];
TableCell usrName = gvRow.Cells[0];
string userName = usrName.Text;
....
How can I manage to change LinkButton text and CommandName depending on that integer data?
P.S I tried Eval but I couldnt figure out whats going on....
I would simply return the data from your data source, as intended. Then I would use an Update Panel to avoid the Postback that will occur from your Link Button. As for the text modifying I would use Javascript, so Javascript will read the page on the client. So when your data source returns:
One
One
Two
One
The Javascript can analyze those rows, then modify the internal cell within the Grid quite painless.
An example of Javascript:
$(".Activator").each(function () {
if ($(this).prev().find(':checkbox').prop('checked')) {
$(this).text("Deactivate");
}
});
This example will validate if a checkbox is checked, if it is modify the internal text to the class .Activator.
Then the internal item in the Grid for code on front-end would look like:
<asp:TemplateField HeaderText="Active">
<ItemTemplate>
<asp:CheckBox
ID="CustomerCheck" runat="server"
Checked='<%# Eval("Active") %>'
Enabled="false" />
<asp:LinkButton
ID="lbCustomerActive" runat="server"
Text="Activate"
CommandName="OnActivate"
ToolTip='<%# "Activate or Deactivate Course: " + Eval("CourseID") %>'
OnClick="CustomerCheck_Click"
CssClass="Activator">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
As you can see, as the internal data is changed the Javascript will automatically adjust the value for me every time the Data Source is binded again. Which the CustomerCheck_Click would execute the code on the server, which will read the Command Argument which contains the Row Id. Which will Update that particular record without a problem and rebind the Grid. (Partially lied, I'm parsing the Tooltip).
You would instantiate on server side like:
((LinkButton)sender).ToolTip;

Add email url to gridview row, and open email window on double click

I have a GridView that has a column that contains emails. I want the user to be able to double click the row and an email link is activated to open an outlook window for an email. I've got the double click part down, but I'm no sure how to get the email from the row to create the url. I'll paste the code I do have below.
<asp:GridView ID="gvAllDOL" runat="server" Visible="False" PageSize="25" AutoGenerateColumns="False" OnDataBound="gvAllDOL_DataBound" DataSourceID="odsDOAll" OnRowDataBound="gvAllDOL_RowDataBound" DataKeyNames="sintDistrictOfficeID" OnRowCommand="gvAllDOL_RowCommand" OnSelectedIndexChanged="gvAllDOL_SelectedIndexChanged">
<Columns>
<asp:ButtonField Text="DoubleClick" CommandName="DoubleClick" Visible="false" />
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblid" runat="server" Text='<%# Bind("sintDistrictOfficeID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="sintDistrictOfficeID" HeaderText="id" SortExpression="sintDistrictOfficeID" />
<asp:BoundField DataField="vcharDOLOfficeName" HeaderText="DOL Office Name" SortExpression="vcharDOLOfficeName" />
<asp:BoundField DataField="vcharDOLCity" HeaderText="City" SortExpression="vcharDOLCity" />
<asp:BoundField DataField="vcharDOLState" HeaderText="State" SortExpression="vcharDOLState" />
<asp:BoundField DataField="intBatchCount" HeaderText="Number Batches" SortExpression="intBatchCount" />
<asp:BoundField DataField="intCaseCount" HeaderText="Number Cases" SortExpression="intCaseCount" />
<asp:BoundField DataField="intExamCount" HeaderText="Number Examiners" SortExpression="intExamCount" />
</Columns>
</asp:GridView>
protected void gvCE_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onMouseOver", "Highlight(this)");
e.Row.Attributes.Add("onMouseOut", "UnHighlight(this)");
// Get the LinkButton control in the second cell
LinkButton _doubleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
// Get the javascript which is assigned to this LinkButton
string _jsDouble =
ClientScript.GetPostBackClientHyperlink(_doubleClickButton, "");
// Add this JavaScript to the ondblclick Attribute of the row
e.Row.Attributes["ondblclick"] = _jsDouble;
}
}
protected void gvCE_RowCommand(object sender, GridViewCommandEventArgs e)
{
string email = ((Label)gvCE.Rows[0].Cells[1].FindControl("lblEmail")).Text; (this doesn't work)
GridView _gridView = (GridView)sender;
string _commandName = e.CommandName;
switch (_commandName)
{
case ("DoubleClick"):
Response.Redirect("<a href=mailto:" + email + ">");
break;
}
}
protected override void Render(HtmlTextWriter writer)
{
foreach (GridViewRow r in gvAllDOL.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl00");
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl01");
}
}
foreach (GridViewRow r in gvCE.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl00");
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl01");
}
}
base.Render(writer);
}
Convert your email field into template one. Add the following code and then try playing with it:
<asp:HyperLink ID="EmailLink" runat="server" Text='Email' NavigateUrl=
"mailto:" + '<%# Eval("yourBoundEmailFieldNameHere") %>'
</asp:HyperLink>
I would use Manul's suggestion on adding the email address through an item template
<asp:HyperLink ID="EmailLink" runat="server" Text='Email' NavigateUrl=
"mailto:" + '<%# Eval("yourBoundEmailFieldNameHere") %>'
</asp:HyperLink>
This way you can access the email address and people can see who they will be emailing.
then add this script to the page
$("table tr").dblclick(function () {
var mailto_link = $('a', $(this)).attr('href');
window = window.open(mailto_link, 'emailWindow');
if (window && window.open && !window.closed)
window.close();
});
then remove the code that is adding javascript functions to each row in the grid, because it is no longer needed.
here is a jsfiddle link http://jsfiddle.net/gorrilla/jEX7Y/
You can use command argument to pass the email address, greatly simplifying the logic necessary to retrieve the address.
Change the Command button column to an TemplateField and add a asp:button inside. Then add the attribute CommandArgument to the button.
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="dblClick" runat="server" Text="dblClick"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
CommandName="dblClick" />
</ItemTemplate>
</asp:TemplateField>
Then in the code behind
protected void gvCE_RowCommand(object sender, GridViewCommandEventArgs e)
{
string email = e.CommandArgument;

Binding RowCommand to fire when any cell in a row is clicked

My GridView basically displays a summarized version of data in the database.
What I want to do is set it up so that when you click anywhere in a row in the GridView, it should execute a set procedure that'll hide the panel that contains the GridView and display a panel that will show you the details of the item you clicked.
<asp:Panel runat="server" ID="pnlList">
<div class="rightalign">
<asp:Label runat="server" ID="lblCount"></asp:Label>
</div>
<asp:GridView runat="server" ID="gvItems" DataKeyNames="mailid"
AutoGenerateColumns="false" onrowdatabound="gvItems_RowDataBound"
Width="100%" OnSelectedIndexChanged="gvItems_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkSelect" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label runat="server" ID="lblStatus" Text='<%# DataBinder.Eval(Container.DataItem, "status") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="firstname" HeaderText="From" SortExpression="firstname" />
<asp:BoundField DataField="datesent" HeaderText="Date" SortExpression="datesent" DataFormatString="{0:yyyy/MM/dd HH:mm}" />
<asp:BoundField DataField="subject" HeaderText="Subject" SortExpression="subject" />
</Columns>
</asp:GridView>
</asp:Panel>
<asp:Panel runat="server" ID="pnlMail">
<p>From: <asp:Label runat="server" ID="lblFrom"></asp:Label><br />
Sent On: <asp:Label runat="server" ID="lblDate"></asp:Label><br />
Subject: <asp:Label runat="server" ID="lblSubject"></asp:Label></p>
<p><asp:Label runat="server" ID="lblMessage"></asp:Label></p>
</asp:Panel>
I figured I'd use the SelectedIndexChanged event, but I'm not sure how to actually make it fire off clicks on the cells.
Here's the code I've got:
protected void gvItems_SelectedIndexChanged(object sender, EventArgs e)
{
int index = gvItems.SelectedIndex;
string mailid = gvItems.DataKeys[index].Value.ToString();
getMailDetail(mailid);
pnlMail.Visible = true;
}
protected void getMailDetail(string id)
{
int mailid = int.Parse(id);
MySqlContext db = new MySqlContext();
string sql = "select m.datesent, m.subject, m.message, u.firstname, u.lastname from mail m inner join users u on m.senderid = u.userid where m.mailid = #id";
List<MySqlParameter> args = new List<MySqlParameter>();
args.Add(new MySqlParameter() { ParameterName = "#id", MySqlDbType = MySqlDbType.Int32, Value = mailid });
MySqlDataReader dr = db.getReader(sql, args);
if (dr.HasRows)
{
dr.Read();
lblFrom.Text = (string)dr["firstname"] + " " + (string)dr["lastname"];
lblDate.Text = (string)dr["datesent"];
lblSubject.Text = (string)dr["subject"];
lblMessage.Text = (string)dr["message"];
}
dr.Close();
}
How can I make clicks on the cells in a row fire an event that'll do the work I need done?
Any help will be appreciated!
I can see two possible solutions here. First - handle click on the row on client side, send Ajax request to some HttpHandler that will return you necessary mail details, and display the returned info. Steps to achieve this:
Assign a client side handler too row click:
protected void gvItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onClick"] = "showMailDetails(" + DataBinder.Eval(e.Row.DataItem, "id") + ")";
}
}
And define the client side function:
function showMailDetails(mailId) {
$.get(
url: 'url to HttpHandler here',
data: {id: mailId},
success: function(data) {
var pnlMail = $('#<%= pnlMail.ClientID %>');
// display data here
pnlMail.show()
});
}
Another way is to handle click on client side and then emulate RowCommand event by doing something like this:
protected void gvItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onClick"] = ""javascript:__doPostBack('" + gvItems.ClientID + "','MailDetailsCommand$" + DataBinder.Eval(e.Row.DataItem, "id") + "')";
}
}
And then on server side go like you already did, just in RowComamnd handler:
protected void gvItems_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "MailDetailsCommand") {
// ...
}
}
Although I would not recommend this method - using _doPostBack manully is not considered as a best practice.
you give a template field which consist the button or a button field and then you can the give the commandname as something and then you can use the gridview commandeventargs and based on the commandname you can do whatever you want, and you can use the OnRowCommand to fire an event :D hope this will help you .....
You can even go for adding the onclick attribute to the cell in the RowDataBound Event, if there are any restrictions of not having the button field or like that

Programmatically access GridView columns and manipulate

I have a GridView :
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" GridLines="None"
HorizontalAlign="Left" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1" onrowcommand="GridView1_RowCommand1">
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:TemplateField HeaderStyle-Width="150">
<HeaderTemplate>
<b>Downloads</b>
</HeaderTemplate>
<ItemTemplate>
<!-- <asp:HyperLink ID="hyperlinkDownload" runat="server" NavigateUrl="" >Download
MP3</asp:HyperLink> -->
<asp:LinkButton CommandName="download"
CommandArgument='<%# Eval("Name") %>' runat="server">Download MP3</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView>
I want to query the value of a particular field in a DB and if it's true, display the LinkButton. if false, I want the linkButton not to be displayed.
is there a way to access the GridView programmatically and make visible certain of its columns or manipulate its items ?
help.
You can do this by adding a handler to the RowDataBound event. Add an event handler along this lines of this in your code behind:
protected void myGrid_RowDataBound(Object sender, GridViewRowEventArgs e)
{
var data = e.Row.DataItem as DataRowView;
if (data != null)
{
var lbtDownload = e.Row.FindControl("lbtDownload");
lbtDownload.Visible = (bool) data.Row["HasFileForDownload"];
}
}
In your markup, attach the event handler to the grid:
<asp:GridView OnRowDataBound="myGrid_RowDataBound" ...>
You will also need to assign an id to the LinkButton, matching the one that you are search for using the FindControl() method in the event handler.
Disclaimer: I am on currently a Linux machine with no chance of testing this. Please report any bugs in the code - feel free to correct them if you have editor rights.
Yes there is.
1) You need to subscribe the RowDataBound event.
2) Give the LinkButton an ID.
3) Insert in codebehind
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton _bt = e.Row.FindControl("ID") as LinkButton;
if(_bt != null)
{
// have a look at the e.row.DataItem and try to get the value of your desired visibility property
_bt.Visible = true;
}
}
}
4) If this does not work with accessing the DataItem, start thinking about a LinqDataSource.

Categories