Help with GridView Update w/ Object Data Source needed

A

anyeone

I've got a GridView bound to an Object Data Source and I'm having trouble
figuring out just how to set it up to update properly.

I have the object data source defined as so:

<asp:ObjectDataSource ID="objBatchData" runat="server"
SelectMethod="GetItems" TypeName="MyNamespace.BatchData"
DataObjectTypeName="MyNamespace.BatchItem" UpdateMethod="UpdateItem" >
<SelectParameters>
<asp:QueryStringParameter Name="BatchID" QueryStringField="BatchID"
Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:parameter Name="ItemID" Type="Int32" />
<asp:parameter Name="BatchID" Type="Int32" />
<asp:parameter Name="DataField1" Type="string" />
<asp:parameter Name="DataField2" Type="string" />
</UpdateParameters>
</asp:ObjectDataSource>

..

BatchItem is a business object that defines several constructors. The
BatchItem(DataRow row) constructor is the one that GetItems() uses to
instantiate individual BatchItems when the object data source binding occurs.
There is also a BatchItem(int ItemID) constructor and a default constructor
that doesn't actually do anything.

ItemID and BatchID are read only and brought in through BatchItem on the
original select statement. DataField1 and 2 are the two fields actually
being updated by the user through dropdownlists bound to BatchItem.DataList1
and BatchItem.DataList2 respectively

The static BatchData.GetItems method seems to be working properly as the
grid is being populated with the correct data.

The static BatchData.UpdateItem method takes in a BatchItem object (since I
got an error when I defined it to explicitly take in ItemID, BatchID,
DataField1, DataField2 saying it needed to take in a BatchItem as a
parameter). It then creates a collection of SqlParameters and calls a stored
proc to perform the update.

The problem is, when the row is updated, the application is instantiating a
default constructor version of BatchItem which is empty and passing that to
BatchData.UpdateItem().

So what I need to figure out is how to get the data from the GridView row
being updated (the four properties listed in "UpdateParameters" on the object
data source) into the BatchItem that is passed to BatchData.UpdateItem().

I've been using some of Phillip Williams' examples to model from (if you're
listening, Phillip), particularly the "DropdownList within a GridView"
example and where I see a disconnect is that the UpdateParameters don't seem
to be tied to anything in the grid data particularly. Unfortunately without
being able to view the source of his UpdateOrder method (the UpdateMethod on
his object data source) I can't compare what I'm doing to what he is doing to
see the problem.

Am I supposed to be overriding one of the GridView events to stuff a
ConfirmItem object with the correct field data? The UpdateItem method only
takes ConfirmItem so I don't seem to have access to a parameters collection.

Help is greatly appreciated, thanks! If you need more information please
let me know.
 
P

Phillip Williams

The update parameters pass scalar values to an object of type clsOrder.
Notice that the clsOrder definition,
http://www.webswapp.com/CodeSamples/ViewSource.aspx?file=\aspnet20\clsOrder.cs,
has a default constructor (without any parameters defined). It has public
properties matching the names of the parameters passed through the
objectDataSource.

The empty constructor allows the ObjectDatasource to instantiate the class
then the ObjectDataSource parameters set the public properties of the class
before passing it to the method specified by the UpdateMethod attribute.

So to answer your question
… how to get the data from the GridView row being updated
(the four properties listed in "UpdateParameters" on the object
data source) into the BatchItem that is passed to
BatchData.UpdateItem()â€

Make sure that your definition of the BatchItem class contains a default
constructor that receives no parameters, e.g.

Public class BatchItem
{
public BatchItem(){ //default constructor }

// the rest of the class implementation
}
 
P

Phillip Williams

Or I should have rather said: Make sure that your definition of the BatchItem
class contains a default constructor that receives no parameters and that it
has public properties to set the values of its data with names matching those
used by the scalar parameters that are defined in the ObjectDataSource.
 
A

anyeone

Hi Phillip,

I do have a default constructor defined (it is being called properly) and I
have properties for all of the parameters, however none of the set methods
are being called on any of the properties.

When I step through the code, first the BatchItem() constructor is called,
then the UpdateItem(BatchItem) method, but none of the setters are called at
all.

If I declare the objBatchData_Updating event just so I can take a look at
the BatchItem being created, I see it is totally empty (as it is when it
reaches the UpdateItem method).

So it seems that for some reason the application can't figure out to
automatically call the set methods even though the property names match the
name and type on the UpdateParameters.

The only thing I am seeing different is that I have other properties on the
object that I do not have explicitly listed as UpdateParameters that are
display only and not needed for the update stored proc - but I don't know why
that would be a problem. They all define set methods just in case though.

Any ideas?

Thanks,
Anye
 
P

Phillip Williams

I can simulate the problem you are describing if I replace the 2-way
databinding on the controls with one-way only, e.g, if I replace Bind by
Eval. In this case there are no parameters to be updated and the
ObjectDataSource would not update them. Could that be the reason in your
case?
 
A

anyeone

It doesn't look like it - I've tried it both ways (using Bind and Eval). Of
course - both fields that are changing are coming from a dropdown list so if
for some reason the grid isn't checking those dropdown lists for changed
values then it might think nothing changed? This wasn't something you were
doing in your example so I'm not sure I wired up the dropdownlists right.

Here's my GridView definition:

<asp:GridView ID="grdBatch" runat="server" DataSourceID="objBatchData"
EnableViewState="False" AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ItemID" HeaderText="ID" Visible="false"
ReadOnly="True" />
<asp:BoundField DataField="BatchID" HeaderText="BatchID"
Visible="false" ReadOnly="True" />
<asp:BoundField DataField="BatchIndex" HeaderText="Batch #"
ReadOnly="True" />
<asp:BoundField DataField="ItemNum" HeaderText="Item"
ReadOnly="True" />
<asp:TemplateField HeaderText="Data Field 1">
<ItemTemplate>
<asp:Label ID="lblDF1" runat="server" Text='<%#
Bind("DataField1") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlDF1" runat="server" DataSource='<%#
Bind("DF1List") %>' DataTextField="DF1Description"
DataValueField="DF1Code"></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DataField2">
<ItemTemplate>
<asp:Label ID="lblDF2" runat="server" Text='<%#
Bind("DataField2") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlDF2" runat="server"
DataSource='<%# Bind("DF2List") %>' DataTextField="DF2Description"
DataValueField="DF2Code"></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>

</Columns>
</asp:GridView>


I have tried it both as is and replacing the dropdown list Bind with "Eval"
in the EditItemTemplates. BatchIndex and ItemNum are for display only and
are not part of the update parameters.

Thanks again for the help!
 
A

anyeone

Ok, I tried for yucks making some of the read-only fields editable and as
soon as I did the set methods started being called - but still not for the
dropdown list fields (those properties stayed null).

So the problem has to be that the app doesn't know that it has to get the
new value for the DataField1 and DataField2 fields from the dropdownlists.

What else do I have to do to those particular templates?":
<asp:TemplateField HeaderText="Data Field 1">
<ItemTemplate>
<asp:Label ID="lblDF1" runat="server"
Text='<%# Bind("DataField1") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlDF1" runat="server"
DataSource='<%#Bind("DF1List") %>'

DataTextField="DF1Description"
DataValueField="DF1Code"></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
 
P

Phillip Williams

Of course it does not. Your code shows that the dropdownlist is bound to a
list named DF1List whereas your DataField1 is bound to a label. You might
need to update your label with the SelectedValue of the dropdownlist on
SelectedIndexChanged if you want it to be saved in the BatchItem object.

In my demo I did not update the values that were browsed by the
dropdownlist. This is why I did not implement such a function. (But now I
might add this to the demo when I get some free time; tomorrow perhaps)
 
A

anyeone

Ok, after several google searches on various key concepts I've finally got it
working. There were a couple of things that had to be wired:

1) grdBatch_RowDataBound needed to select the proper item from the
dropdownlist when in edit mode

2) Set the hidden fields (ID, BatchID) that are needed for the update query
as key fields using DataKeyFieldNames property of the grid - if they aren't
DataKeyFields you can't find the values since the columns are hidden

3) grdBatch_RowUpdating needed to explicitly set the DataField1, DataField2,
and the hidden field values by finding the dropdownlist controls and getting
the values of the data key fields.

Part of my problem in finding the info on how to do this is that some of the
information seems tied to the object data source and some seems tied to the
GridView so the tidbits of knowledge needed to fully wire it were spread all
across the API. (Which is why good, thorough examples are worth their
weight in gold! Thanks to Phillip and others who take the time to provide
them.)

Phew. Time to go home.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top