Question: Regarding GridView boundfield ReadOnly property - asp.net

I have a Gridview boundfield where i set ReadOnly to true because i don't want user to change its value. However on the objectdatasource control's update method that boundfield became null when i try to use it as parameter in update method. Is there a way to set that value during updating?

No, just add the field name you need to the DataKeyNames attribute of the GridView. Then the value will be sent to the Update command.

When you mark a field as read-only on the GridView it renders on the page as a span element, not an input. Therefore the value is not available on PostBack. If you can construct the update statement so that it doesn't expect this field, that would be the best way to deal with this. If the update statement is autogenerated and you can't get around having the value to update, then you can either read the value from the database before doing the update (so that you have it) or include a HiddenField bound to this column and use a literal that obtains the value via Eval instead of binding (if necessary). This will require using a template.
<asp:TemplateField>
<InsertItemTemplate>
<asp:TextBox runat="server" ID="itemTextBox" />
</InsertItemTemplate>
<EditItemTemplate>
<asp:HiddenField runat="server" ID="itemHF" Value='<% Bind("Item") %>' />
<asp:Label runat="server" ID="itemLabel" Text='<% Eval("Item") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label runat="server" ID="itemLabel" Text='<% Bind("Item") %>' />
</ItemTemplate>
</asp:TemplateField>

Another approach is to add a new query to your tableadapter. Create an update query that just uses the fields desired to be updated. When selecting the update method on the ODS pick the update query. The BoundFields that are not part of the update query can now be turned to readonly=true and it should work.

I had a similar problem and solved it in a slightly different way. But in my case the parameter I wanted to use in my Update method was my primary key and was available in a Query string. So in my DataSource definition I defined the UpdateParameters section to use instead of . Then I was able to remove the parameter completely from my table and it would revert to the Query string parameter.

Related

Set a DropDownList SelectedValue to a bound field with sometimes null value

I have a situation where I have a gridview which is populated from a sql table which editing is allowed. For one of the fields, I have it so the user has to select a value from a drop down box in the edit template for the gridview.
<asp:TemplateField HeaderText="Department" SortExpression="Department">
<EditItemTemplate>
<asp:DropDownList ID="ddlEditDepartment" runat="server"
SelectedValue='<%# Bind("Department") %>'>
<asp:ListItem>Department 1</asp:ListItem>
<asp:ListItem>Department 2</asp:ListItem>
<asp:ListItem>Department 3</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblDepartment" runat="server" Text='<%# Bind("Department") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
If you select "edit" for a record in which this field already has a value stored in the table for it, no problem. However, if you select "edit" and there is no value in the table for it yet, you get the following error
'ddlEditDepartment' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
How can I account for blank or null values in this situation and make this work?
You're binding your DropDownList to a field named "Department" in your GridView's datasource:
SelectedValue='<%# Bind("Department") %>'
It's kind of a hack, but you could modify the query that populates the Department field of your GridView to account for the nulls (by coalescing them out):
SELECT COALESCE(Department, "No department entered") AS Department
FROM YourTable
And then just add that as kind of a "default" option in your dropdown:
<asp:ListItem>No department entered</asp:ListItem>
It sounds like you are trying to update a record that does not exist. So, you have a few options, depending on what you want to do. You could capture the error and display a user friendly alert to the user that they need to create a new record before editing. Or, you could capture the error and run an insert command if the error gets raised. Or you could prevent the error from firing all together. This would be my suggestion. In your code behind, when the dropdowlist event fires, take the ID and run a query to see if the record exists. If it does, update it. If not, either alert the user or you could just do the insert then. If you have a specific question on how to do this, let me know.

Accessing Gridview row data inside fields

I have a Gridview bound to a linqdatasource. The gridview has a FK. i want to display a name/text field instead of the key field for this column.
I have created a method in my ASP.NET page that basically GetLookupForKey that returns the string when provided the key. However, I don't know how to send the column data for the specific row in the data declaration.
This should make it clear:
<asp:TemplateField>
<ItemTemplate>
<asp:Literal ID="RoleName" runat="server" Text='<%#
GetRoleName(* I need to send in the RoleId Here*) %>' />
RoleId is both a boundfield and a DataKeyName. How can I send the RoleId to my method? Additionally, how can I achieve this without using any codebehind?
Thanks
I can see two ways right now, maybe there are even more.
1) With code behind
<asp:Literal ID="RoleName" runat="server" Text='<%# GetRoleName(Eval("RoleId")) %>'/>
This one will require a protected method GetRoleName(object roleId) in the page's code behind class.
2) Without code behind
I assume that objects Role and whatever object is referencing it are both declared in the Linq context. If so, Linq can (and even does it by default behavour) generate properties for referenced objects. That is, when you have a table with FK to Role, the corresponding object will have both RoleID and Role properties. Therefore everything can be accomplished declaratively:
<asp:Literal ID="RoleName" runat="server" Text='<%# Eval("Role.Name") %>'/>

Multiple databound controls in a single GridView column

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.

ListView Inserting Event - ListViewInsertEventArgs Values collection is empty

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.

ASP.NET: How to assign ID to a field in DetailsView?

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.

Resources