How to "bind" invisible and unbound field in ASPXGridView EditFromTemplate? - asp.net

I have an ASPxGridView with edit form template. DataSource for this grid is EntityServerModeSource which is a read-only data source. I use this combination because it delegates filtering and sorting to database server.
For simplicity I will present simplified scenario.
My EntityServerModeSource return rows with fields A,B and C.
What I do for update is following. In EditFormTemplate I have controls which I bind to fields A and B. Something like:
<asp:TextBox Text='<%# Bind("A")%>' />
<asp:TextBox Text='<%# Bind("B")%>' />
For update I have a stored procedure which expects 3 parameters A, B and C. In RowUpdating of ASPxGridView event I check for e.NewValues collection. The problem is that it only contains fields A and B and not C. This is expected and normal because field C was not bound to any control. E.g. NewValues["C"] returns null. But I need the old value of C so I can pass it to stored procedure which expects all three. I cannot just make up a some value because this would overwrite existing value in database.
My hacky solution was to make a dummy control inside EditFormTemplate, bind it to field C and make it invisible like so:
<div style="display: none">
<asp:TextBox Text= '<%# Bind("C")%>' />
</div>
Now, the field C is bound and in RowUpdating event I can access it with e.OldValue["C"].
But this is a hacky solution and I dont like it. Is there a way to "bind" field C in code-behind or in some way to force field C to appear in OldVaues and NewValues collections?

For getting values which are not bound to a UI element use the ASPxGridView.GetRowValues method. Pass the FocusedRowIndex and the column name of the column, then cast it to your desired type.
string C = ASPxGridView.GetRowValues(ASPxGridView.FocusedRowIndex, "C") as string;

Related

ASP.NET - Trying to implement SortParameterName property to SqlDataSource

I have several Gridviews and Repeaters bound to SqlDataSources using stored procedures. I am trying to implement sorting functionality into some of these but am having a hard time finding concrete instructions and/or examples of what is required on the SqlDataSource side to generate the ORDER BY's needed. Particularly, I do not understand the point of having a SortParameterName property in the SqlDataSource if all it does is manually connect to an ORDER BY clause in the stored procedure. Why define it as such if it is just another parameter in the SelectParameters list like any other, but just so happens to be connected to the ORDER BY clause? When I run the code example below, I am told there are too many arguments specified (obviously, the extra SortParams argument). Do I really need to alter my stored procedures and add "ORDER BY #SortParams" clauses to the end of the existing queries to make this work? I feel like I am missing something.
SqlDataSourceInLine.SelectParameters.Clear()
SqlDataSourceInLine.SelectCommandType = SqlDataSourceCommandType.StoredProcedure
SqlDataSourceInLine.SelectCommand = "ApproverGetApproved"
SqlDataSourceInLine.SelectParameters.Add("CompanyID", ConfigurationManager.AppSettings("Temp_CompanyID"))
SqlDataSourceInLine.SelectParameters.Add("SortParams", "EmpName DESC")
SqlDataSourceInLine.DataSourceMode = SqlDataSourceMode.DataSet
SqlDataSourceInLine.SortParameterName = "SortParams"
Dim dv As DataView = SqlDataSourceInLine.Select(DataSourceSelectArguments.Empty
Any clarification would be appreciated!
I was just trying to figure out how to use the SortParameterName and found this question. After doing some more search I think I have now found the correct answer.
Microsofts page Sorting Data with Data Source Controls says as follows (my emphasis):
The parameter identified by the SortParameterName property is passed to the ObjectDataSource control's SelectMethod or passed as part of the parameter collection to the SqlDataSource control's SelectCommand. The ObjectDataSource control can use the information passed to it in the sort parameter to return the data in sorted order. For the SqlDataSource control, you must supply the name of a stored procedure that can take the sort parameter and return the sorted data, because you cannot pass a parameter as part of an ORDER BY clause.
This indicates that the answer given by Icarus is not correct.
My conclusion is that when the SortParameterName property is set (in combination with an appropriate stored procedure) the Gridview will not do the sorting itself, but will let the datasource do a so called Custom Sorting, which for example would be the necessary way to sort if Custom Paging is used.
Update:
I have now used it in my own programming and confirmed that my conclusion was correct.
I've never used the SortParamter in the past, but what I gather from the documentation is that the purpose of this parameter is to allow you to get the results sorted in the way you want them in case the stored procedure does not do it already. Other than that, you don't need to use it for anything. A GridView whose datasource is of type SqlDataSource already implements sorting out of the box. You simply need to set the AllowSorting property to True and the SortExpression on every column.
Example:
<asp:GridView ID=" productsGridView" Runat="server"
DataSourceID="SqlproductDataSource" AutoGenerateColumns="False"
AllowSorting="True" >
<Columns>
<asp:BoundField HeaderText="Product"
DataField="ProductName" SortExpression="ProductName">
</asp:BoundField>
...
Nothing is required on the SqlDataSource. You need to implement the Sorting event for the Gridview and something else for the repeaters since they don't have sorting built in. What you could do (if you have small datasets coming back) is to use ViewState and store your DataTable of results and then utilize the DataView and the sorting capability of that, then bind the Repeaters/GridViews to the sorted DataView. You still have to keep track of the SortDirection and SortParameter within ViewState, regardless.

Text='<%# Eval("LocationType")%> vs Text='<%#Bind("LocationType") %>'>

What is the difference in:
Text='<%# Eval("LocationType")%> vs Text='<%#Bind("LocationType") %>'>
Thanks
The Bind keyword works like Eval to display data and can retrieve the value you've entered when updating or inserting a record.
In addition, Bind is very useful in TemplateFields used in the GridView and DetailsView. Bind stores the value of the bound control property into a collection of values that the FormView control automatically retrieves and uses to compose the parameter list of the insert or edit command. The argument passed to Bind must match the name of a field in the data container.
For example, the textbox in the code snippet provides the value for the notes field.
' />
The .NET Framwork 2.0 introduces Eval(). Eval() is a shortcut for Container.DataItem().
Since Eval() uses Reflection, it causes overhead. From a optimization standpoint, it is better to use Container.DataItem().

ASP.NET DetailView InsertItemTemplate

I have a InsertItemTemplate defined in my DeatilView control. Within this template I have a number of fields that the user fills and a number of fields that are filled automatically and the user cannot change them. These values are coming from an object stored in session.
Code looks like this: (I only mention necessary parts, if you need anything more let me know)
<asp:DetailView ... DataSourceID="MyDataSource" ...>
<Fields>
...
<InsertItemTemplate>
// These are the fields filled by the system
<asp:Label ... Text='<%# some value from session object %>' />
<asp:Label ... Text='<%# some value from session object %>' />
// some textboxes here that user fills,
//they use Bind("some data source value here") to send their data to database
...
</InsertItemTemplate>
...
</Fields>
</asp:DetailView>
Now the problem is where I need to actually insert values into database.
Textbox values are sent just alright, but since I haven't bound label values they are not sent to DataSource. So I'm asking how to do this?
An alternative I found was to pass a DefaultValue to DataSet's
respective InsertParameter but I don't know how to fill that area to
get it's value from Session.
Another alternative is to set Parameter's value (not default value)
to be taken from Session, which is possible but this only support
values that are directly within Session, and I'm passing the value of
a property inside an object that's stored in Session. Is there a
way to get this fixed, other than storing values inside Session
directly.
What type of DataSource are you using? I need to know it, because there is few ways to obtain parameters from session depending on type of datasource.
detailView_ItemInserting(object sender, DetailsViewInsertEventArgs e) is called just before inserting the data, you can use detailView.FindControl method in this event to get access to Label controls.

asp.net dropdownlist selected value if the value does not exist

I have a control that holds a dropdownlist that holds variables (A, B, C, N/A). The variables are pulled from a class. When an item is submitted, in the database it will store the letter and an identifier. If the database entry with the identifier exists, this code runs fine, if the database does not hold an identifier for the entry (it does not exist yet) then I get an error.
Code:
<EditItemTemplate>
<asp:DropDownList runat="server"
ID="ddlQualityTypes"
DataSource='<%# CodeLists.QualityTypes() %>'
DataTextField="strCode"
DataValueField="strCode"
SelectedValue='<%#Eval("strQualityCode")
== null ? "A" : Eval("strQualityCode") %>'
/>
</EditItemTemplate>
Any ideas on how to get around this?
EDIT: strQualityCode is the name of the variable that is databound to the object holding which letter corresponds to the item.
I would make the field nullable in the database, and make it an optional parameter in your stored procedure. If the value of the dropdown is null or empty, don't pass the parameter to the stored procedure.

DataKeys dataList

This is my bare DataList definition :-
<asp:DataList runat="server" ID="dtltrial"
ondeletecommand="dtltrial_DeleteCommand" DataKeyField="PhotoId" >
</asp:DataList>
where PhotoId is my primary key of table and so i have given it as datakeyField. However i also want AlbumId along with DataKeyField. How do i specify it in DataKeyField and later on retrieve it in ondeletecommand event of DataList?
Thanks in advance :)
You can specify:
DataKeyNames="PhotoId,AlbumId"
Update:
It looks like the DataList doesn't allow you to specify multiple keys, and then retreive them as normal. From this question, the accepted answer deals with a GridView. Unfortunately the DataList doesn't function the same.
You'll likely have to create a unique identifier yourself at the datasource, or create a hybrid on a databinding event. For example, "PhotoId_AlbumId", which would turn into "837_7826". On the delete event, you'd then have to extract out the two IDs, separated by the underscore.
Consider creating a new single primary key on the datasource instead.

Resources