GridView.SelectedIndexChanged doesn't fire - c#

Hello i have a gridview that is connected to the event selectedindexchanged and is on a hidden panel but when i try to fire the event don't do anything.
This is the code of the gridview:
<asp:GridView ID="GridView1" runat="server" CssClass="mGrid"
Width="847px" onselectedindexchanged="GridView1_SelectedIndexChanged2">
<Columns>
<asp:ButtonField Text="Borrar" />
</Columns>
</asp:GridView>
This is the code on the event:
protected void GridView1_SelectedIndexChanged2(object sender, EventArgs e)
{
GridViewRow row = GridView1.SelectedRow;
Response.Write(row.Cells[2].Text);
}

That's because that button isn't a SelectButton, one approach would be to set the AutoGeneratesSelectButton property on the GridView to true. You could then get rid of that other button you're trying to make work.
If you need that other button then you'll need to make it a CommandField and set the ShowSelectButton to true. With that configuration you can set the SelectText and have some custom text for the button.
Either way, a Button isn't going to do anything for SelectedIndexChanged.

Related

How do I get the row I clicked with a button

I have a grid view and when I click on the button I wanted to do a SQL command to see which Order number was pressed. How do I get the row I have clicked on?
asp
<asp:GridView ID="GridView1" runat="server"
DataKeyNames="No_" AutoGenerateColumns="false" style="color:Black;border-collapse:collapse;margin-right: auto;display: table;text-align: center;" OnPageIndexChanging="MyGrid_PageIndexChanging" OnRowDataBound="MyGrid_RowDataBound" AllowPaging="True" PageSize="20" AllowCustomPaging="False" >
<Columns>
<asp:BoundField DataField="No_" HeaderText="No_Encomenda" />
<asp:BoundField DataField="[Item No_]" HeaderText="Item number" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" OnCheckedChanged="CheckBox1_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerSettings Mode="NumericFirstLast" PageButtonCount="4" FirstPageText="First" LastPageText="Last"/>
<PagerStyle CssClass="gridview" HorizontalAlign="Center" VerticalAlign="Middle"/>
</asp:GridView>
cs
protected void ButtonDetails_Click(object sender, EventArgs e)
{
MyGrid.Visible = false;
GridView1.Visible = true;
}
Gridview image:
Well, first of all, in your markup, I don't see a button in your markup. So the picture you have, and the markup don't agree with each other.
There are about 3 great ways to get the row click with a button.
Most common:
Drop in a the button. Say like this:
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="Details" CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
Note how we added the CommandName = "select". This is a special option that will trigger the Gridivew RowIndexed changed. It ALSO triggers the row command. But, in row command the "selected row event" has not yet triggered. So, I just ignore the row command event, and put your code in the selected index changed event.
protected void MyGrid_SelectedIndexChanged(object sender, EventArgs e)
{
// Get selected row
GridViewRow dG = MyGrid.SelectedRow;
Response.Write("Row index was " + dG.RowIndex.ToString());
// get non templated columns - they appear in cells
Response.Write("2nd colum value = " + dG.Cells[1].Text);
// get templated fields - say a combo box for city
DropDownList CityComboBox = (DropDownList)dG.FindControl("DropDownList1");
Response.Write("City selected from combo box = " + CityComboBox.SelectedValue);
}
So by JUST adding the CommandName = "Select", then this will trigger the SelectedinddexChanged event.
Another way is to use the row command (but you have to pass the row index to that event).
But, a really slick way is to 100% ignore the grid events, and JUST use your button.
You can do it this way:
Drop in the button. But now you can't double click on the button to wire up the click event, but you CAN STILL set the event for the click.
While in the markup you can thus type in OnClick= NOTE VERY careful the intli-sense that pops up - it looks like this:
So in the above choices - choose the create new event - it SEEMS like nothing occurred, but when you flip back to code-behind, you have a nice simple clean, good old regular button click event.
Droop a button - create click event. You can now just 100% ignore the complex GridView events (and that select command etc.).
You do this way now:
protected void Button3_Click(object sender, EventArgs e)
{
Button MyButton = (Button)sender;
GridViewRow dG = (GridViewRow)MyButton.Parent.Parent;
Response.Write("Row index was " + dG.RowIndex.ToString());
// get non templated columns - they appear in cells
Response.Write("2nd colum value = " + dG.Cells[1].Text);
// get templated fields - say a combo box for city
DropDownList CityComboBox = (DropDownList)dG.FindControl("DropDownList1");
Response.Write("City selected from combo box = " + CityComboBox.SelectedValue);
}
I find the above is less hassle, but also LESS learning curve to use. We drop in a button - click event. You just pick up the "sender" into a button, and then get parent.parent which turns out to be the grid row we want.
The first parent is I think some cell divider. In fact I use this .parent trick all the time. Thus buttons are a simple button dropped into the grid markup, and we use the standard button click event and code approach.
But, hey, we really don't care about the GridVieew row command, and we really dont' care about the Selected index changed.
We have a button click. So now you can use this slick trick to save world poverty's, save using complex GridView events, and just code up a simple button like any other button.
And we get FULL USE of the grid view row with this trick.

How to fire Image Button click event in infragistics webdatagrid in C#?

I am using Infragistics (v. 12.2) WebDataGrid in which I have TemplateFieldColumn with Image button.
I want to capture the click event of this Image button. How to achieve that?
I have below code sample –
<asp:Panel runat=”server”>
<ig:WebDataGrid ID=”sampleWebGrid” runat=”server” AutoGenerateColumns=”False” Width=”100%”>
<Columns>
<ig:TemplateDataField Key=”keyBtnApply” Header-Text=”update”>
<ItemTemplate>
<asp:ImageButton ID=”btnUpdate” runat=”server” CommandName=”U” Width=”30px” Height=”30px” CommandArgument=”args” ImageUrl=”~/Images/Blue-Button-Icon.png”>
</ItemTemplate>
< /ig:TemplateDataField>
</Columns>
</ig:WebDataGrid>
</asp:Panel>
You can attach to the event from the markup like:
asp:ImageButton ID="btnUpdate" runat="server" OnClick="imageBtn_Click"
or define it in Page_Load event like:
ImageButton imageBtn = (ImageButton)sampleWebGrid.Rows[0].Items[0].FindControl("btnUpdate");
imageBtn.Click += imageBtn_Click;
void imageBtn_Click(object sender, ImageClickEventArgs e)
{
}
However you need to loop though all rows to find the control on the given row if you go with this approach

GridView Button reference on rowdatabound

I feel like I'm missing something obvious here but I'm just not getting it. I have a gridview with a template field column where i have a button and a hidden field. I'm trying to get the reference to both the button and the hidden field on row databound, as both the button's label and commandargument etc change depending on the other row data.
If i place a breakpoint in the area indicated in the code below, I can see that the hidden field is being assigned to properly, but the button is not. What am I missing here?
GridView.aspx
<asp:GridView ID="gvCurrentQueueStatus" runat="server" AutoGenerateColumns="False"
OnRowDataBound="gvCurrentQueueStatus_RowDataBound">
<Columns>
<asp:TemplateField ItemStyle-HorizontalAlign="Center" HeaderText="Service Controls">
<ItemTemplate>
<asp:Button ID="btnSubmitCommand" runat="server" Text="Control" OnClick="btnSubmitCommand_Click" />
<asp:HiddenField ID="hdnQueueNumber" runat="server" Value='<%# Eval("ReportQueueNumber") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
GridView.aspx.cs
protected void gvCurrentQueueStatus_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button controlButton = (Button)e.Row.FindControl("btnSubmitCommand"); // FindControl fails
HiddenField hdnQueueNumber = (HiddenField)e.Row.FindControl("hdnQueueNumber"); // FindControl succeeds
// Other stuff
} // breakpoint here, successfully finds htnQueueNumber, but not btnSubmitCommand
}
Try this:
Button controlButton = e.Row.FindControl("btnSubmitCommand") as Button ;
Or try this way:
foreach (GridViewRow row in gvCurrentQueueStatus.Rows) {
Button controlButton = (Button)gvCurrentQueueStatus.Rows[row.RowIndex].FindControl("btnSubmitCommand");
}
So apparently my button was in fact getting properly assigned to, it was just not reporting as such when mousing over the variable in my debugger.
I'm not actually crazy, Visual Studio's debugger is however and needed the old "have you tried turning it off and on again".
Sorry about that those that helped look into my issue :3

Event not firing after setting OnClientClick in RowDataBound

I have an Asp.net GridView (populate with a data binding).
One of my columns is a ButtonField (obviously with his own CommandName).
The GridView_RowCommand works perfectly, but if i add a GridView_RowDataBound (in which I simply add a javascript confirm) the GridView_RowCommand event is not fired in the PostBack.
What could be the problem/solution?
Adding code for better understanding:
Aspx code:
<asp:GridView ID="GridView1" runat="server"
OnRowCommand="GridView1_RowCommand"
onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="MyField1" HeaderText="MyField1" />
<asp:BoundField DataField="MyField2" HeaderText="MyField2" />
<asp:ButtonField Text="MyAction" ButtonType="Image" ImageUrl="myaction.gif" CommandName="myaction" />
</Columns>
</asp:GridView>
c# code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
(e.Row.Cells[e.Row.Cells.Count - 1].Controls[0] as ImageButton).OnClientClick = "javascript:return confirm (\"Do action?\");";
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "myaction")
{
DoMyAction();
}
}
EDIT:
I forgot to tell that my GridView is inside an ajax TabContainer (AjaxControlToolkit)
this is what is emitted normally for the Image button:
<input type="image" src="myaction.gif" alt="MyAction" onclick="javascript:__doPostBack('GridView1','myaction$1')" style="border-width:0px;" />
when you set OnClientClick in your code-behind, it will prepend your code but still add the __doPostBack function call, resulting in the following html:
<input type="image" src="myaction.gif" alt="MyAction" onclick="javascript:return confirm('Do action?');javascript:__doPostBack('GridView1','myaction$1')" style="border-width:0px;" />
the onclick event handler will return before it gets a chance to do the postback properly (it will just submit the form).
Doing this:
(e.Row.Cells[e.Row.Cells.Count - 1].Controls[0] as ImageButton).OnClientClick = "if (!confirm('Do action?')) { return false; }";
should allow the client-side click event to run the __doPostBack function and raise the RowCommand event server-side as expected when the user clicks OK.
(As a side-note, this is a good example of one of the drawbacks of ASP.NET WebForms - there is a lot of html being generated that you just have no control over. ASP.NET MVC FTW!)
At first glance this seems fine. Have you tried running your code outside the TabContainer?
It might get you in the right direction.
Use sender as argument on ClientScript.GetPostBackClientHyperlink function so it will create client js event dinamicaly. Bellow the example in RowDataBound, where sender is GridView (VB).
YourCommand will be passed as argument for RowCommand event to be raised.
e.Row.Cells(columnIndex).Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(sender, "YourCommand$" & e.Row.DataItemIndex))

DetailsView FindControl() returns null after some postbacks

I've been working for a long time with GridViews and DetailsViews, but yesterday I've come across a new scenario, which I quite do not understand.
I have a GridView with ImageButton (CommandName="Insert") which will change the mode of the DetailsView to Insert. Afterwards I'll look for a DropDownList inside that DetailsView and add some items dynamically. Works fine, but one first the first time I press that ImageButton. If I click on "Cancel" in the DetailsView and press the ImageButton again, the .FindControl() Method returns null. What life cycle problem am I facing here?
I've created this sample: (To make it run in your Visual Studio, just bind a DataSource to the DetailsView, otherwise it will not be rendered)
Markup:
<asp:GridView ID="gvCategory" runat="server" OnRowCommand="gvCategory_RowCommand">
<Columns>
</Columns>
<EmptyDataTemplate>
<asp:ImageButton ImageUrl="~/images/add.png" ID="ibAdd" runat="server" CommandName="Insert" />
</EmptyDataTemplate>
</asp:GridView>
<asp:DetailsView ID="dvCategory" runat="server" Width="150px" AutoGenerateRows="false"
AutoGenerateInsertButton="True" DataSourceID="LinqDataSource1">
<Fields>
<asp:TemplateField HeaderText="foo">
<InsertItemTemplate>
<asp:DropDownList ID="ddlCategory" runat="server" Width="150"></asp:DropDownList>
</InsertItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView><asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="WebApplication1.DataClasses1DataContext"
TableName="Categories"></asp:LinqDataSource>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.gvCategory.DataBind();
}
}
protected void gvCategory_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert")
{
this.dvCategory.ChangeMode(DetailsViewMode.Insert);
DropDownList _ddlCat = (DropDownList)this.dvCategory.FindControl("ddlCategory");
if (_ddlCat != null)
{
_ddlCat.Items.Clear();
_ddlCat.Items.Add(new ListItem() { Text = "-- empty --", Value = "-1" });
}
}
}
I have also tried using a ItemTemplate, and not a InsertItemTemplate, but this results in the same. After using the ChangeMode-Method the DetailsView.CurrentMode == InsertMode. The only thing I can think of is, that the markup is already generated for the ItemTemplate and changing the Mode to InsertMode can't affect the rendered markup, or something like this.
Does anybody have a solution to this? =)
I think you are on the right track. It's hard to tell without seeing all of the code, but basically any time you change the rendering mode of a row in a repeater-type control you need to rebind it so that it's re-rendered. The fact that FindControl is returning NULL means only one thing: THE CONTROL IS NOT THERE. Which means it was not rendered. You can verify this by looking at the control hierarchy.
So, in your handler for Cancel are you rebinding?

Categories