posted on Wednesday, February 02, 2005 8:48 AM
by
mlorengo
Further Refinement with the ObjectDataSource Control
In order to take advantage of the new GridView control in Asp.Net 2.0, I've
been researching how too use the new ObjectDataSource control, and add support
for it in my Virtual Cellar application. I now have two classes in the Virtual
Cellar Model that will serve as the candidate classes for use as an
ObjectDataSource. A lot of Asp.Net 2.0 examples use the SqlDataSource control to
illustrate the GridView features, this entry will list some resources that
specifically apply to using the ObjectDataSource
As I mentioned in my last post, I was trying to determine how to prevent the
GridView from being populated on the first page load. I found the following note
in the ObjectDataSource documentation.
The
ObjectDataSource
control retrieves data whenever the
Select
method is called. The
Select
method is automatically called by controls bound to the
ObjectDataSource
when their DataBind method is called. If
you set the DataSourceID property of a
data-bound control, the control automatically binds data when a Web page loads.
However, if you set the DataSource
property, you must explicitly call the DataBind
method of the data-bound control. You can call the
Select
method programmatically at any time to retrieve data.
So, it turns out that specifying the DataSourceId property autobinds the
control. This is more of that "no-code" model in Asp.Net 2.0. In order to
suppress the autobind, I simply removed the DataSourceId attribute from my .aspx
page. This prevents the GridView from being populated on the page load. It also
removes the link between the GridView and the ObjectDataSource, so I now have to
setup a TextChanged handler do to the binding.
protected void ProducerSearchTextbox_TextChanged(object sender, EventArgs e)
{
producerGridView.DataSource = producerDataSource1;
producerGridView.DataBind();
} |
The above snippet sets the DataSource property to my ObjectDataSource
control's Id property. This is equivalent to setting the DataSourceId =
"producerDataSource1" property in the .aspx page, except that it doesn't
autobind on page load. Then I call the DataBind() method.
I refactored a lot of the Repository code right out of my model. My reason
for doing this was to satisfy a requirement that the ObjectDataSource have a
parameterless default constructor. It turns out that you can overcome this
requirement by handling the ObjectCreating event on the ObjectDataSource and
performing my own construction. As it turns out, the new code model seems to fit
better, and I eliminated a lot of classes that I just don't need yet if ever. My
new class diagram looks like this.

Bigger picture here
The WineDataSource and ProducerDataSource replace the WineRepository and
ProducerRepository classes. The Builder classes are responsible for creating
actual instances of the Wine and Producer classes, thereby segregating the
responsibilities of each class. In order to make the *DataSource classes more
friendly to the DataSource configuration wizard, I've decorated them with the
following attributes.
[DataObject]
public class WineDataSource
{
public WineDataSource()
{
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public IList<Wine> SelectByProducerId(int id)
{
return GetWineList(this.wineProvider.GetByProducerAsDataReader(id));
}
[DataObjectMethod(DataObjectMethodType.Select)]
public IList<Wine> SelectById( int id )
{
return GetWineList(this.wineProvider.GetAsDataReader(id));
}
//...
} |
The DataObject attribute on the class level tells the wizard that this is a
DataSource class. The DataObjectMethod attribute exposes the
SelectByProducerId(int id) as a DataObjectMethod, and more specifically a
"Select" method. The second boolean argument specifies that this is the default
"Select" method. Here's how it looks in the designer.

The only items that will display in the drop down list are those that have
been marked with the [DataObject] attribute (as long as the Show only data
components checkbox is selected). This eases the clutter when your project
consists of a lot of classes.
The next step is to choose the Select method. Again, only those methods with
a DataObjectMethod and a DataObjectMethodType of Select will be shown.

In conclusion, I've illustrated how to prevent the autobinding from occurring
on the page, refined my class diagram to reflect the addition of the new
xxxxDataSource classes, and demonstrated the use of the DataObject attributes
(which are in System.ComponentModel).