Gridview cell value on RowCommand - c#

I'm attempting to get the cell value from a gridview but running into a few issues. I have setup my code similar to this example except that I'm adding my button fields on the server side. For some reason RowCommand is firing twice when clicking the cell values? TIA for any help
Page Load is empty:
code
protected void Page_Load(object sender, EventArgs e)
{
}
Adding Button Field:
code
foreach (DataColumn col in transposedTable.Columns)
{
ButtonField bfield = new ButtonField();
bfield.DataTextField = col.ColumnName;
bfield.HeaderText = col.ColumnName;
bfield.CommandName = "ColumnClick";
gvTest.Columns.Add(bfield);
}
The RowDataBound and RowCommand events are the same as the example link above

ok...There seems to be an open bug in MSFT connect...
GridView RowCommad Event Firing Twice
seems like there are some workarounds posted in the Workarounds tab...
Hope this helps...

This is a known bug. I had the same problem.
I removed the Handles GridView.RowCommand from the code behind event declaration, and
added this line to the properties declaration for the grid in the .aspx source:
OnRowCommand="GridView_RowCommand"
Worked perfectly.

One way to access row values in a grid is to use the Cells collection along with the grid's current index (which you can access via the eventargs) as shown below
void YOUR_GRID_EVENT(Object sender, GridViewDeleteEventArgs e)
{
Grid.Rows[e.RowIndex].Cells[0];
}
you can also make use of the findcontrol as below:
var txtName = e.Row.FindControl("txtName") as TextBox;
Hope this helps...
Update
Also check your code to make sure that you are calling the GridView's DataBind() method appropriately...because every time you call GridView.DataBind()...the rowcommand event of the grid view gets called...I think (guessing) you currently have a gridView.DataBind() in your onload as well as in the button click event..so that might cause the rowcommand event to be called twice...if this is not the case then post some code so that we can explore more...

Related

Set the 'onClick' to call a client method when dynamically adding control in Code Behind

I am dynamically adding a RadioButtonList in the Code Behind. I want it so that the 'OnClick' does not call JavaScript, but instead it calls a method in my code behind.
Is this possible?
In addition, is there a way to set it up so that this say control has runat="server"?
You can use the Button Click Event
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.click(v=vs.110).aspx
Yes, it is possible. Also, there is no need to have runat="server" since your are creating the control in code.
You need to set your RadioButtonList object's OnSelectedIndexChanged event. As #Robert mentioned, if you are creating controls dynamically you need to wrap them in the Page_Init().
protected void Page_Init(Object sender, EventArgs e) {
RadioButtonList radiobuttonlist = new RadioButtonList();
radiobuttonlist.SelectedIndexChanged += radiobuttonList_CheckedChanged;
//Set the AutoPostBack to true proptery to that the user action
// will immediately post-back to the server
radiobuttonlist.AutoPostBack = true;
}
private void radiobuttonList_CheckedChanged(object sender, EventArgs e) {
//Code you want to execut when a user selects a different item
}
Reference: https://msdn.microsoft.com/en-us/library/System.Web.UI.WebControls.ListControl.SelectedIndexChanged(v=VS.110).aspx
Be sure to add the control in the Page_Init() portion of the code, not in Page_Load() or later. Set up the event handler += line inside the Page_Init() setup. The control should run server side if you do this. I'm not sure if runat="server" will be explicitly set but the control will behave that way.

ASP.Net LinkButton Does not update on first post back

Inside a ListView Control's <ItemTemplate> I'm using a LinkButton.
When the List populates it has a set of LinkButtons. The link button text's are generated from a column in the records retrieved using a data source.
When I click on a LinkButton, I need it's text to be captured into either a hidden field or view state during the post back, so that it will be displayed in a Label or TextBox when page post back happens.
But it does not happen on first page post back. Instead, I have to click on the LinkButton twice for two post backs for the value to be displayed in Label/TextBox.
How can I get it done in the first post back ?
I have tried the same without the ListView, using just a LinkButton as below, and get the same outcome.
protected void LinkButton_Click(object sender, EventArgs e)
{
LinkButton selectedButton = (LinkButton)sender;
HiddenField1.Value = selectedButton.Text;
ViewState["LinkButtonText"] = selectedButton.Text;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(HiddenField1.Value))
{
Label1.Text = HiddenField1.Value;
}
TextBox1.Text = HiddenField1.Value;
if (ViewState["LinkButtonText"] != null)
{
if (!string.IsNullOrEmpty(ViewState["LinkButtonText"].ToString()))
{
ViewStateTextBox.Text = ViewState["LinkButtonText"].ToString();
}
}
}
Well, It happens since the sequence of the server side method execution. The page load before hand, then the control click methods, in that order. Instead of updating hidden field like that now using a client side JavaScript function OnClientClick of the LinkButton control, which updates the hidden field.
In short, you use it everytime you need to execute something ONLY on first load.
The classic usage of Page.IsPostBack is data binding / control initialization.
if(!Page.IsPostBack)
{
//Control Initialization
//Databinding
}
Things that are persisted on ViewState and ControlState don't need to be recreated on every postback so you check for this condition in order to avoid executing unnecessary code.
Another classic usage is getting and processing Querystring parameters. You don't need to do that on postback.

Generate postback to specific method/event handler

I have a custom gridview, and i'm generating a postback event for onclick manually on RowDataBound. However, this postback ALWAYS goes to/expects a specific method on the row click.
Here's my current code to make that postback happen:
if (!String.IsNullOrEmpty(this.OnRowClick))
e.Row.Attributes.Add("onclick", this.Page.ClientScript.GetPostBackEventReference(this.grid1, "Select$" + e.Row.RowIndex.ToString()));
As you can see here, i've setup a property to my grid to ask which method to call when executing that postback... however, i cannot seem to find anywhere on the web how to specify in the _dopostback call WHICH method to call... it always, without exception, expects this method:
grid1_SelectedIndexChanged(object sender, eventargs e)
But I don't want that. I want it to go to whatever method name is contained in the property OnRowClick.
Here's how things are currently setup for the visual people:
that's just it... i'm not sure. I am a visual person so maybe this will help a bit for everyone as well:
Custom Control Setup (minified version):
[ Some other controls
-= A gridview =-
Some other controls]
[(Control Event Property)
OnRowClick Event (GridViewRow eventarg)]
[(Control Event Wireup)
if(OnRowClick!=null)
this.GridView1.SelectedIndexChanged += InternalMethod(...)
[(InternalMethod(...))
GridViewRow row = this.GridView1.SelectedRow;
if(OnRowClick!=null)
OnRowClick(row);]]
So far so good... no problems whatsoever... BUT... when i set it up like this:
HtmlPage
-> Custom Control(mygrid)
---> mygrid.OnRowClick += SomePageMethod(GridViewRow row)
------> SomePageMethod never, ever, gets called... like... never...
Since i have built my control as a composite control, i can't step through its internal code to debug, so i can't tell why it's not happening... :S please please help me bubble up this event properly!
Custom Control Code:
this.grid1.SelectedIndexChanged += new EventHandler(grid1_SelectedIndexChanged);
void grid1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = this.grid1.SelectedRow;
if(this.OnRowClick!=null)
OnRowClick(this.grid1, row);
}
#region Events
public delegate void RowClickEventHandler(object sender, GridViewRow SelectedRow);
[Category("Events")]
[Description("This event fires when a row is clicked, if it is defined")]
public event RowClickEventHandler OnRowClick;
#endregion
Web page code:
this.pgrSummary.OnRowClick += new SimplePager.SimplePager.RowClickEventHandler(pgrSummary_OnRowClick);
And that methode never gets called...

Is it possible to stop ObjectDataSource from auto-binding?

I have a GridView to which I've using an ObjectDataSoure as the data source. The ObjectDataSource is taking in parameters from a TextBox and DropDownList which is then passed into the stored procedure. There is also a button called Search which can be used to force a refresh on the GridView by providing/changing values in the TextBox and/or DropDownList. However I noticed that if I changed the values I don't have to click on the Search button; simply clicking on the GridView causes a data bind.
Is there anyway to prevent this action while still using the ObjectDataSource?
When you assign a DataSourceID on the GridView, the grid will automatically bind to the ObjectDataSource. You can simply omit that property on the GridView and wait until the Search button's click event to assign it.
The problem is that every time any parameter used for ObjectDataSource is changed the ODS performs a "DataBind".
You can use two HiddenFields to keep the values. The ObjectDataSource will only do a "DataBind" when you change the values on the HiddenFields. So you can change the values on the TextBox and DropDownList, and when you want a "DataBind" you only need to copy the values to the HiddenFields.
Here is a code sample I made for another question: Q11874496WebApp.7z
In my case i just used a private boolean field in codebehind and respect its values on datasourceName_Selecting event.
For example i declared the following:
private bool IsInSearchingMode = false;
set it true only in search mode:
protected void btnSearch_Click(object sender, EventArgs e)
{
this.IsInSearchingMode = true;
this.gridData.DataBind();
}
and then check the value on Selecting event:
protected void myLinqDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
e.Result = new List<BranchDataClass>();
if (!this.IsInSearchingMode)
return;
// e.result = select code
}
A drawback is that a new page_load that is not caused by btnSearch_Click will reset the private variable's value. If you want it to be persistent you should use a hidden field as proposed or save it to viewstate.

DropDownList.SelectedValue changes (as a child control in a FormView) aren't sticking

Okay, I have a FormView with a couple of child controls in an InsertItemTemplate. One of them is a DropDownList, called DdlAssigned. I reference it in the Page's OnLoad method like so:
protected void Page_Load(object sender, EventArgs e)
{
((DropDownList)FrmAdd.FindControl("DdlAssigned")).SelectedValue =
((Guid)Membership.GetUser().ProviderUserKey).ToString();
}
Basically I'm just setting the default value of the DropDownList to the user currently logged in.
Anyway, when the page finishes loading the SelectedValue change isn't reflected on the page. I stepped through OnLoad and I can see the change reflected in my Watch list, but when all is said and done nothing's different on the page.
I figured it out. I'm still missing exactly why it doesn't work just on FormLoad, but performing the change in the FormView's DataBound event does the trick.
protected void FrmAdd_DataBound(object sender, EventArgs e)
{
// This is the same code as before, but done in the FormView's DataBound event.
((DropDownList)FrmAdd.Row.FindControl("DdlAssigned")).SelectedValue =
((Guid)Membership.GetUser().ProviderUserKey).ToString();
}
So, I guess the general rule of thumb is that if you are having problems making changes to controls when working with databinding, try to make them immediately after it has been bound.
I had a problem with dropdownlists and making the first value say something like, "Please select a value..." but without making it an actual selectable item, nor show up on the dropdownlist. I was binding the ddl in the page_load and I have to make sure that I set the text of the dropdownlist, AFTER it's been bound with data. You've accomplished the same thing by adding it to your databound section.

Categories