I have a grid view that is data bound to a dataset. In a grid I have a column DefaultValue, which has three controls in it - a dropdownlist, a checkbox and a textbox. Depending on the data that is coming in it can switch to any of these controls. Everything is simple enough when we need just to display data - in gridview_prerender event I simply make one of the controls visible. The control is setup like following:
<asp:TemplateField HeaderText="Default Value" SortExpression="DefaultValue">
<ItemTemplate>
<asp:TextBox ID="txt_defaultValue_view" runat="server" Text='<%# Bind("DefaultValue") %>' Enabled ="false" />
<asp:DropDownList ID="ddl_defaultValue_view" runat="server" Enabled ="false" />
<asp:CheckBox ID="chk_defaultValue_view" runat="server" Enabled ="false" />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_defaultValue_edit" runat="server" Text='<%# Bind("DefaultValue") %>'/>
<asp:DropDownList ID="ddl_defaultValue_edit" runat="server" />
<asp:CheckBox ID="chk_defaultValue_edit" runat="server" />
</EditItemTemplate>
</asp:TemplateField>
My problem starts when I am in edit mode and I need to update the grid with new data. Since only the textbox control is databound, the RowUpdating event can only access data from the textbox column and all of my other data simply gets discarded. I also can't databind with checkbox and dropdownlist control, since they can get an invalid data type exception. So, does anyone know how can I update a column that has three different controls, where each of these three controls might have a valid data?
Thanks
First, i would switch visibility of the controls in RowDataBound of the Grid and not on PreRender, because it can only change on DataBinding and not on every postback.
You can there also bind the Dropdown to its datasource, change the checked-state of the Checkbox and set the Text-property of the Textbox according to the the Dataitem of the Row.
When you update you can find your controls with FindControl in RowUpdating and get their values(f.e. Dropdownlist.SelectedValue).
GridView has pair of events:
RowUpdating/RowUpdated
RowDeleting/RowDeleted
....
In your case your need RowUpdating - is called right before update is performed, So find in row expected control (saying checkbox) and make preparation before pass to database
As another way review possibility to use ObjectDataSource event Updating - it is usual way to specify parameters for query execution.
Related
This sounds a lot like a bunch of other questions on here, but nothing I've read follows what I'm seeing.
I have a gridview that contains a number of bound fields and a couple of template fields containing checkboxes. The gridview is bound to a custom datasource on pageload (inside a "not page.ispostback()" condition). The user can check the checkboxes to specify certain actions that are then committed when a link button is clicked.
The link button's click event has the following code in it:
For Each row As GridViewRow In UnpaidEntriesGridView.Rows
Dim paidCheckbox As CheckBox = CType(row.FindControl("PaidCheckbox"), CheckBox)
If paidCheckbox.Checked Then
// perform database action
End If
Next
Initialise() // (this rebinds the gridview)
No matter what I do, I cannot get hold of the checked value of any checkbox in the gridview that the user has changed. All checkboxes remain in their original state (set on data bind).
This is more than likely a page life-cycle issue, but for the life of me, I can't figure out why the user's changes aren't persisted after postback, despite the fact that the gridview isn't rebound until after I've checked.
ViewState is enabled, everything's pretty standard here otherwise.
Gridview code snippet from ascx follows:
<asp:GridView ID="UnpaidEntriesGridView" runat="server" AutoGenerateColumns="false" EnableViewState="true">
<Columns>
<asp:BoundField HeaderText="Entry Name" DataField="EntryName" />
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="PaidCheckbox" runat="server" EnableViewState="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:LinkButton ID="UnpaidEntriesSaveLinkButton" runat="server" Text="Commit Changes" />
Any help (even a slap for being so stupid) would be massively appreciated.
I have datagridview with multiple columns in my asp.net website. And I am displaying a backend sql stored procedure output into this grid using page OnLoad event. First column in the grid contains a checkbox. I have added this checkbox through ItemTemplate, so that all rows will have a checkbox for selecting the row. I want user able to select the checkbox and based on this selection I would like to perform a DB operation.
currently i am using like below, but couldn't able to trigger the event.
<asp:GridView ID="resultGridView" runat="server" >
<Columns>
<asp:TemplateField HeaderText="Processed">
<ItemTemplate>
<asp:CheckBox ID="CheckBoxProcess" runat="server" OnCheckedChanged="resultgrid_CellContentClick"
Checked="false" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
on my code behind, I have method resultgrid_CellContentClick() for checkbox selection change event. But this code, never executed when select checkbox on/off.
You didn't set AutoPostBack="true" in your checkbox, that's why your checkbox event handler did not work. Just set it...
<asp:CheckBox ID="CheckBoxProcess" AutoPostBack="true" runat="server"
OnCheckedChanged="resultgrid_CellContentClick" Checked="false" />
Given the following InsertItemTemplate (simplified) I'm not getting anything back in the event object's Values collection.
<InsertItemTemplate>
Item:
<asp:DropDownList ID="ItemInsertType"
DataTextField="SearchItemName"
DataValueField="SearchItemID" runat="server" />
Hide Location:
<asp:TextBox ID="txtItemHideLocation" Text='<%# Bind("HideLocation") %>' runat="server"></asp:TextBox>
<asp:Button ID="btnSearchSearchItemInsert" CommandName="Insert" runat="server" Text="Add" />
<asp:Button ID="btnSearchSearchItemInsertCancel" CommandName="Cancel" runat="server" Text="Cancel" />
</InsertItemTemplate>
I'm binding the listview to a collection attached to my nHibernate model object (SearchObject.SearchItems). This collection doesn't have insert or update handling like an object datasource would, so I want to handle the insert/update events manually. Is there a way to get these values to come through automatically, or do I have to manually grab each value from its control when I handle this event?
I was using reflector on that assembly, and it looks to me (could be wrong) that it only supports IBindableControl controls for automatic extraction into the Values collection. So Values would not contain an entry for any non-IBindableControl-supporting controls. TextBox does not implement this, nor does DropDownList.
I typically use the InsertItem property and extract the control references directly using FindControl.
HTH.
I have a master-detail page, in which I use GridView to display multiple rows of data, and DetailsView + jQuery dialog to display the details of a single records. only one DetailsView is open at a time.
I need to be able to pull out a single field of the open DetailsView, for manipulation using JavaScript. Is there a way to give a unique ID to a given field in DetailsView, so I can use getElementByID? Or is there another way to accomplish what I'm trying to do?
Thank you in advance.
If you are using a bound textbox in a template field in your detailsview you can then select it by:
$("[id$='MyTextBox']");
Which will find the textbox bound to MyFieldName as below.
<asp:DetailsView ID="DetailsView1" runat="server">
<Fields>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="MyTextBox" Text='<%# Bind("MyFieldName")%>' runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
Whatever guff asp.net adds onto the begining of the id won't matter because jQuery $= mean "ends with".
there may be a better way, but when I've needed an id available for js work, I just convert the bound field to a templated field. you can then give the textbox the id of your choice. keep in mind when rendered the id will be expanded with the id of the parent control.
A typical situation:
In my GridView control, I have a Footer row which contains a Textbox and an "Add" Button. When the button is pushed, the Text entered in the TextBox is added to the grid. I also have a validation control to require that, when the button is pushed, that text has been entered in the TextBox. After a new row is added, the textbox is clear to allow for easy entry of the next item.
The user may also edit the text in previously entered rows by clicking the Edit LinkButton, which puts the row into edit mode. Clicking an Update LinkButton commits the change.
The problem:
When, I click the Update link to commit the changes, if text has not been entered in the Footer row's TextBox (the row used to add a new entry), the validation control returns a "Entry Required" error. It should only require an entry if the Add button is pushed, not if the Update LinkButton is pushed.
It seems that the server side Validation control's validating event fires before the GridView's RowCommand event or the btnAdd_Click event, so I am wondering how, from the server, I can determine what event fired the postback so I can determine whether what edits should be performed for the given situation.
I am using a mix of client side "required" validation edits as well as more complex server sides. Since I probably have to have some server sided validations, I would be happy with just knowing how to handle server sided validations, but really, know how to handle this situation for client validations would also be helpful.
Thanks.
Convert your CommandField into a TemplateField, and in the EditItemTemplate, change the Update LinkButton's CausesValidation property to false.
Update:
Converting to a TemplateField is simple and doesn't require any code changes (just markup):
Changing the CausesValidation property to false in the markup is also straightforward:
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="lnkUpdate" runat="server" CausesValidation="False"
CommandName="Update" Text="Update"></asp:LinkButton>
<%--
More controls
--%>
</EditItemTemplate>
<ItemTemplate>
<%--
Controls
--%>
</ItemTemplate>
</asp:TemplateField>
Now, if you want your footer and data rows to be validated separately, you need to use validation groups, which is explained in Microsoft's documentation. All the controls in the same validation group will have their ValidationGroup property set to the same value, like this:
<asp:LinkButton ID="lnkUpdate" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" ValidationGroup="GridViewDataRowGroup">
</asp:LinkButton>