asp.net gridview - select row - asp.net

I'm looking to be able to click on a gridview row in order to select a row rather than use the select link.
I have the code below which make the row clickable and act like a hyperlink.....
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If (e.Row.RowType = DataControlRowType.DataRow) Then
e.Row.Attributes.Add("onmouseover", "this.style.cursor='hand';this.style.textDecoration='underline';")
e.Row.Attributes.Add("onmouseout", "this.style.textDecoration='none';")
e.Row.Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" + e.Row.RowIndex.ToString()))
End If
End Sub
....but then I get the error message:
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Anyone know how to overcome this?
Thanks,

Thanks for help had found the answer another way...rather than use the visibility property
I set the display property to none and everything worked as is...
<asp:CommandField ShowSelectButton="True" ItemStyle-CssClass="HiddenColumn" HeaderStyle-CssClass="HiddenColumn"/>
.HiddenColumn{display:none;}

Adrian Godong's comment is correct. The easiest way to correct this is to set the GridView to still generate the Select LinkButton, but set its Visible property to false. Finally, set the onclick event to fire a virtual click on the Select LinkButton. This way, the ASP.NET event will come directly from the Select button and you will therefore not be caught be an invalid postback security check.

You could also use "RegisterForEventValidation".
Check this:
RegisterForEventValidation .net 3.5 gridview row, how to?

Related

Save the checked status of a CheckBox included inside an ASP ListView

I know there are similar questions about this issue (for example, here and here) but no one results helpful for my problem.
I have a ListView control showing all the users registered in the database and there is a CheckBox for each user shown if the user is approved or not, and I wanna save the changes directly when the CheckBox's Checked property changes.
I know it's not correct to add the event handler on the ListView_ItemDataBound, because after the CheckBox's AutoPostback there is not a new binding, thus the event handler get lost. On the other hand, I can't append the method directly on the ASPX file because this way I can't know which user is affected by the change (at least, I think I can't).
Any sugestion?
Thanks a lot
You have a couple of options.
It's possible that the ListView.ItemCommand event might fire. I'm not sure, though, because the documentation just specifies buttons. You might want to experiment.
The other option would be to harness the ListView.ItemCreated command. I believe that this always runs, regardless of whether the ListView is bound or not, because the item always has to be created, even if it's from ViewState. What you would do in the event handler for that event would be to attach an event handler to the CheckBox Click or CheckChanged event (I forget what the server-side name is for a CheckBox state change event).
So i ran into the same problem. i'm curious, on your page load are you checking if its a postback?
if(!Post.IsPostBack){
//normal page load
}
If you don't have that check, it will call your page load logic, in my case it was resetting the checkbox everytime with my data object.
On the aspx on the checkbox OnCheckedChanged="ckbNameOfCheckbox_CheckedChanged" AutoPostBack="true"
In the code behind
Protected Sub ckbNameOfCheckbox_CheckedChanged(sender As Object, e As EventArgs)
Dim chkBox As CheckBox = CType(sender, CheckBox)
' Gets the item that contains the CheckBox object.
Dim item As ListViewDataItem = CType(chkBox.Parent, ListViewDataItem)
NameOfTheListView.UpdateItem(item.DisplayIndex, sender.Checked)
End Sub

How to avoid InvalidOperationException when setting the defaultbutton in ASPX content

I am trying to set a default button in my ASPX page. I have a master page so the form is there. I have a panel in the content page that holds a table that organizes a number of textboxes, dropdowns and other inputs. The last row of the table holds some buttons, one of which I want to be the default button. After doing some research, I have tried the following with no success.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
pnlHolder.DefaultButton = cmdSearchJob.ClientID
I have also tried
pnlHolder.DefaultButton = cmdSearchJob.UniqueID
and
Dim cmdDef As Button = pnlHolder.FindControl("cmdSearchJob")
pnlHolder.DefaultButton = cmdDef.UniqueID
but both throw the exception "The DefaultButton of 'pnlHolder' must be the ID of a control of type IButtonControl.".
I have seen some Javascript solutions, but was hoping to just be able to set the defaultButton for the panel.
Try setting the DefaultButton of the parent Form.
C#:
this.Page.Form.DefaultButton = cmdSearchJob.UniqueID;
VB?:
me.Page.Form.DefaultButton = cmdSearchJob.UniqueID
Similar issue here: Allow Enter key to login in asp.net?
Try setting it to:
cmdSearchJob.ID
The panel will call FindControl to get the Client ID itself
Can you set this inside the control on the front-end?
<asp:Panel id="pnlHolder" DefaultButton="cmdSearchJob">
<asp:Button id="cmdSearchJob" runat="server" Text="Search" />
</asp:Panel>
Also, this may worth knowing, what type of object is cmdSearchJob? Is it a standard asp.net button control?
Finally found what it was. Tried adding another button with no CSS, etc. that just popped up a javacsript alert() for testing. Was able to set that as the default button when it was outside the table. As the submit button is one of a series of buttons (not a very pretty UI, but user requirements and all that) in the table, I used this additional button and set its style to display:none and have it call the same subroutine in the code behind.
So, short answer, it wasn't seeing it in the table.
Thanks everyone for your input.
I still have no idea why it wouldn't set the button.

ASP.NET Button click not caught (button in user control which is dynamically loaded in Repeater)

I have written a user control that captures some user input and has a Save button to save it to the DB. I use a repeater to render a number of these controls on the page - imagine a list of multiple choice questions with a Save button by each question.
I am loading the user control inside the repeater's ItemDataBound event like this (code simplified):
Protected Sub rptAssignments_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptAssignments.ItemDataBound
Dim CurrentAssignment As Assignment = DirectCast(e.Item.DataItem, Assignment)
Dim ctl As UA = CType(LoadControl("~\Controls\UA.ascx"), UA)
ctl.AssignmentID = CurrentAssignment.AssignmentID
ctl.Assignment = CurrentAssignment.AssignmentName
ctl.EnableViewState = True
e.Item.Controls.Add(ctl)
End Sub
FYI, I need to load the control at runtime rather than specify it in the ItemTemplate because a different control could be used for each row.
In the user control, there is a linkbutton like this:
<asp:LinkButton ID="lbnUpdate" runat="server" Text="Update" OnClick="lbnUpdate_Click" />
... and a button click handler like this:
Protected Sub lbnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles lbnUpdate.Click
' my code to update the DB
End Sub
The problem is that when the Save button is clicked, the page posts back, but lbnUpdate_Click is not called. The Page_Load event of the page itself is called however.
I should mention that the repeater is part of a user control, and that user control is loaded inside another user control (this is a DotNetNuke site which makes heavy use of user controls). The Save button link looks like this:
javascript:__doPostBack('dnn$ctr498$AssignmentsList$rptAssignments$ctl04$ctl00$lbnUpdate','')
This problem exemplifies how webforms outsmarts itself.
You have to reconstitute the Repeater, either by re-binding or from viewstate, to have sub-controls raise events. The price you pay is either another trip to your data source or all that redundant data stored on the client in the viewstate. Shameful!
I had a similar problem once that might be the same thing.
In short, since you are dynamically creating the buttons, after the postback they don't exist. Thus, when ASP.NET Webforms looks for the event, it can't find anything.
When does your repeater get databound? Try rendering the buttons to the page again in the postback (even as a test) to see if that does the trick.
Are the UserControl's IDs same on every postback?

Gridview RowUpdating event not firing

I have a Gridview with AutoGenerateColumns="False".
I am using a TemplateField to display my Edit, Update and Cancel 'buttons' in the first column of the GridView within respective ItemTemplate and EditItemTemplate fields.
Within the ItemTemplate I have an ImageButtong with a CommandName of "Edit". This works as expected and I can put a breakpoint in the RowCommand event handler to see the "Event" command name. After it has been clicked the postback places that row in edit mode. All textboxes appear as they are meant to.
At this point in time the above EditItemTemplate is displayed with two ImageButtons within it. One has it's CommandName = "Update" and the other "Cancel".
My problem lies in that the click on the Update ImageButton posts back, but neither the RowCommand nor RowUpdating events get triggered.
I have set the requisite attributes in the GridView tag. (Note, in the gridview the EnableViewState="False" - if I set it to True I get the standard
"Failed to load viewstate. The control tree..." etc. error)
One strange thing that I've noticed that makes me think it's a ViewState problem is that if I change the CommandName of the Update button to "Edit" that postback event does get captured in the RowCommand event...
Any suggestions are welcome. Thanks.
As noted by Asem and Ron, adding the CausesValidation="false" attribute to the CommandField resolved the problem.
The reason was that I had some other validation controls on the page and on the GridView update the page was firing the other validation controls, so I think its better to set a ValidationSummary property.
I had this same situation where my "Edit" button was causing other validations (albeit hidden popups) to execute behind the scene.
From reading the solutions I was looking for the standard CausesValidation="false" property to fix the issue. I was not able to locate that field because it seems as if I was using AutoGenerateEditButton="True" to add my edit buttons to the gridview.
My SOLUTION was as follow and I hope this help you save some valuable time as well.
Set AutoGenerateEditButton="False" this way you can add this field via ASP Code.
Use the code below to add the "Edit" button field to your gridView code as follow.
<asp:commandfield showeditbutton="true" causesvalidation="false" headertext="Edit"/>
If validation was the problem, you would now be able to see your Updating module firing as axpected.
Set the GridView EnableViewState property to true.
Sean,
I understand you have the answer now but for future references you would have to create an addhandler and a delegate to do what you wanted to do. I misunderstood the question at first. But here's what you would do if you chose not to use a command field.
//This is in pageload
If Not IsPostBack Then
'Create new column for Edit buttons
'Dim field As New TemplateField
Dim actionfield As New TemplateField
actionfield.HeaderText = "Action"
Dim actioncol As DataControlField = actionfield
GridView1.Columns.Insert(8, actioncol)//the eight is the column number of where you are adding the column. below you will add the button. You really don't need to add this column programmtically. I normally do though.
End If
//rowcreated
If e.Row.RowType <> DataControlRowType.footer Then
btnedit.ToolTip = "Edits the Current Record"
btnedit.ImageUrl = "\images\bttnEditMini.gif"
GridView1.Rows(i).Cells(8).Controls.Add(btnedit)
btnedit.CommandName = "view"//notice commandname. You can manipulate it.
btnedit.CommandArgument = GridView1.Rows(i).Cells(0).Text
AddHandler btnedit.Click, AddressOf btnedit_Click
end if
//then notice you must create an imageclickeventhandler delegate
Public Delegate Sub ImageClickEventHandler(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Sub btnedit_Click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
//whatever actions you need to take.
end sub
I removed the master page and let the page that contained the GridView inherit from Page, and it worked. Something in my inheritance stack (or something in the MS controls) didn't work the way I had it set up.
This fixed the issue for me:
If Not Master.Page.IsPostBackEventControlRegistered Then
'logic to bind data
End If
if you change the name of the command to 'update' you will have to handle the update in rowcommand which shouldn't be a problem - right?
Check out this Question I asked. It may help
Added
Something you could do is change the commandname to whatever you'd like and handle it in Rowcommand. Make the database updates/inserts manually on rowcommand.
It has been mentioned on this page in other answers that the error is caused by validation. The reason is that there are validators on the page, which quite possibly do not apply to the particular row being edited, and for whatever reason they are not being met. If you want validators to work for your currently editing row, you will not want to set CasuesValidation to false... Instead, you will want to disable any irrelevant validators except those that you care about for the purpose of editing this row.
Find the validators that are not within the edit item template of this gridview row, set them to disabled in page_load.
Let 'CausesValidation' stay true on the template command fields (by default it is true so you can just elide it.) so that anything in the row that you want to validate still gets validated.
Profit.
I also have the same problem in a Gridview with Edit,update,cancel. Edit and Cancel event get fired but never Update Event. Then finally I change the CauseValidation to false for Update linkbuttion form the Edit Template field. It surprisingly works fine.
If you using any function for retrieving(Binding) the grid view from database and calling it in page_Load() event then it may cause this issue. try to call this function in page_LoadComplete() event and it will work.

Controls not retaining values after postback when FormView set to insert mode

I am setting the CurrentMode of a FormView to insert mode using the ChangeMode method in the Page_Load event like so:
if(!Page.IsPostBack)
{
MyFormView.ChangeMode(FormViewMode.Insert);
}
Within my FormView's insert template I have a DropDownList control with it's AutoPostBack property set to true. I also have several other DropDownList and TextBox controls within the insert template.
Whenever I change the selection of the DropDownList and a postback occurs I'm losing all the values entered into the controls. The weird thing is that if I use ChangeMode to set the FormView to insert mode anytime after the initial page load I don't have the problem. I've stepped through the the code with the debugger and everything seems to be happening correctly but sometime after my event handler for the DropDownList runs everything seems to be getting reset.
What is going on here?
Update:
I noticed that my FormView was inside of a div tag with runat="server" and enableviewstate="false". Once I enabled viewstate for the container div I began seeing a slightly different behavior. The FormView still does not retain values after the first postback but now subsequent postbacks work fine and the values are retained.
Any ideas would be greatly appreciated.
This answer from other forum by Walter Wang [MSFT] - 26 Jan 2007 03:29 GMT
First, the problem appears to be that the FormView is told by the data
source control that the data has changed, and therefore it should
rebind to get the new data. This actually should not have been done
since we're still in Insert mode. I have got a workaround for your
reference: Inherit from FormView to create your own FormView control,
override OnDataSourceViewChanged and set RequiresDataBinding to false
if we're in Insert mode:
public class MyFormView : FormView
{
protected override void OnDataSourceViewChanged(object sender,
EventArgs e)
{
if (this.CurrentMode == FormViewMode.Insert)
{
this.RequiresDataBinding = false;
}
else
{
base.OnDataSourceViewChanged(sender, e);
}
}
}
I've tested it on my side and it seems working correctly. Please give it a
try and let me know the result.
Try
MyFormView.EnableViewState = true;
The ViewState loads before PageLoad and my guess is that by changing the Mode on PageLoad recreates another set of controls, the ones in your EditItemTemplate. If it is set by default to Edit Mode, and that you uncomment that line on PageLoad, will it maintain the values? It should if you don't switch the mode.
FormView.ChangeMode(FormViewMode.Insert)
This must work, check Id's and use intelisense?
my example is with a add item form view..
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddNewItemFormView.ChangeMode(FormViewMode.Insert)
End Sub
Try to do it on page load without any "if..then's", if it works you'll know that isn't the expression but maybe the if content or construction.
Remember to make the control IDs meaningful so it will be easier and less likely to do mistakes when you need to use them or call them through intelisense.
Best luck.
:)
I am having the similar issue of viewstate not retained at EditItem template.
Setting EnableViewState = true doesnt help either.
What i do is get the OnUpdated() function, and at the very end of the function,
e.KeepInEditMode = true;
Hope this helps..
try to change mode on Page Init or or Prerender events

Resources