Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems with deleting rows in a GridView

Status
Not open for further replies.

afroblanca

Programmer
Jul 15, 2005
67
US
I'm wanting to leverage the GridView control. However, I don't want to add a DataSource control to my page in the VS .NET designer, because I do not like having data access layer information in the .ASPX.

So this is what I'm trying to do - create my SqlDataSource in a .CS file, and bind it to a GridView in the codebehind. However, it seems like MS really does not want me to do it this way.

My biggest problem has been deletion of rows. What I would really like to do is implement my own event handler for deletion. While it is possible to implement an event handler using the RowCommand event, there doesn't seem to be any way to remove the row from the actual table! GridView.Rows has no Delete() method, and GridView.DeleteRow() just calls the RowDeleting event, which is really no help at all.

So I thought, "Ok, I'll try it the other way. I won't try to implement my own event handler. I'll use the built-in event handlers for row deletion." No luck there either. This is the weird part - If I create the DataSource and wire it up to my GridView in the VS Designer, everything works just fine. HOWEVER, If I create my DataSource and wire it up to my GridView in a .CS, I get the error: "The GridView 'gvSites' fired event RowDeleting which wasn't handled." How come when you create the DataSource in the VS .NET designer, the event is automatically handled?

To be honest, all I really need from the GridView is the table formatting, paging, and sorting. The rest of the bells and whistles I could really do without. I've considered using a DataGrid, but from what I've read, DataGrids have been deprecated, so using them would be unwise.

Has anybody else had any success with implementing GridViews in a way that doesn't require data access layer information to be in the .ASPX? Can you point me to any good articles on the subject? Having data access layer info in the .ASPX offends my sensibilities in ways that I can't even properly explain. Am I correct in thinking this way, or am I being silly and pigheaded?
 
However, I don't want to add a DataSource control to my page in the VS .NET designer, because I do not like having data access layer information in the .ASPX.
All the DataSource control does when dropped onto a page, is create the control in the code behind file, but it puts it in the "Web Form Designer Generated Code" section so that you don't see it.

While it is possible to implement an event handler using the RowCommand event, there doesn't seem to be any way to remove the row from the actual table! GridView.Rows has no Delete() method, and GridView.DeleteRow() just calls the RowDeleting event, which is really no help at all.
That's because the GridView is bound so you don't want to remove rows from the gridview, you want to remove rows from the datasource.

To be honest, all I really need from the GridView is the table formatting, paging, and sorting. The rest of the bells and whistles I could really do without. I've considered using a DataGrid, but from what I've read, DataGrids have been deprecated, so using them would be unwise.
GridView's are available in version 2.0 of the framework as a replacement for the DataGrid so if you are using version 1.1 then you will ahve to use a DataGrid otherwise use a GridView.

Has anybody else had any success with implementing GridViews in a way that doesn't require data access layer information to be in the .ASPX?
See my first point. You can use your own code to create a DataTable and then bind that to the GridView and personally I always do that. I don't like the IDE to write the code for me as it tends to "bloat" it and create things that I don't need.


____________________________________________________________

Need help finding an answer?

Try the Search Facility or read FAQ222-2244 on how to get better results.

 
Thank you for your help.

>All the DataSource control does when dropped onto a page, is create the control in the code behind file, but it puts it in the "Web Form Designer Generated Code" section so that you don't see it.

You must be thinking of .NET 1.x. There is no "Web Form Designer Generated Code" in 2.0.

>See my first point. You can use your own code to create a DataTable and then bind that to the GridView and personally I always do that.

How do you bind a DataTable to a Gridview? It seems that Gridview wants a DataSource of some sort (I've used ObjectDataSource and SqlDataSource)

I've progressed a little bit with this problem. I'm now using an ObjectDataSource instead of an SqlDataSource. This solves some of my problems, but not all of them. I still need to add the ObjectDataSource control to the page, which bothers me. I would like to be able to just create the ObjectDataSource and associate it to the GridView in code.
 
Well, I'd argue first and foremost that there's a difference between having your data layer logic interminged with your UI code and having configuration information in the UI about how the UI is going to use the DAL.

The key advantage of seperation of layers is loose coupling. With that advantage you can, for example, delete any view of the data without having to rewrite code to access the data.

I think the data source framework accomplishes loose coupling sufficiently enough: wizards might exist to configure how the UI will interact with the DAL (through the data sources), but ultimately it doesn't really affect other parts of the system if you delete the .aspx that uses the data source.

What would be an ideal OO solution, however, is to further abstract the DAL into custom collections and objects, then hook the form up to use those objects via the ObjectDataSource.
 
You must be thinking of .NET 1.x. There is no "Web Form Designer Generated Code" in 2.0.
Sorry, that was maybe a bit misleading. There is a section for this generated code in 2.0 but it is actually generated on-the-fly so that you don't have to see it (hence the new Partial classes). Note: in 2.0 windows applications, you can actually see this code by looking in the designer file.

How do you bind a DataTable to a Gridview? It seems that Gridview wants a DataSource of some sort (I've used ObjectDataSource and SqlDataSource)
Yes, the GridView does want a DataSource, so simply point your DataTable at it as you would have doen with a DataGrid e.g.
Code:
myGridView.DataSource = myDataTable
myGridView.DataBind


____________________________________________________________

Need help finding an answer?

Try the Search Facility or read FAQ222-2244 on how to get better results.

 
Hello all,

Just wanted to say that after days of experimentation, I have found a solution to my problem. Thank you all for your help.

I'm still a bit miffed at MS for not offering any tutorials on doing this. To me, this seems like a valid and common thing to want to do. The fact that all their tutorials center around doing things the "simple" way (putting everything in the .ASPX, using the wizards, etc.) really made this very difficult for me. Also, the documentation for GridView is very confusing. I've come to expect this, since MS documentation is often confusing and lacking in useful examples. However, this instance was particularly bad since GridView itself is a very complicated little beastie.

Well, enough complaining. I think that at the end of all this, I'm going to write an article on how to leverage GridView with ObjectDataSource. I can't believe that nobody's done it yet.

Anyway, on with the solution...

To use GridView without putting DAL info in the .ASPX:

1) In your codebehind, define a module-level variable for the ObjectDataSource
2) Override OnLoad. In your OnLoad, call a method in your codebehind that will set up the GridView. We'll call this method InitGrid(). In InitGrid(), you will do the following :
a) Obtain the ObjectDataSource from a method in your data access class (this will be discussed in the next step)
b) Add event handlers to your ObjectDataSource
c) Add your ObjectDataSource to the Page's Controls collection
d) Assign the ID of your ObjectDataSource to the GridView's DataSourceId attribute.
3) In your data access class, implement a method that returns a new ObjectDataSource. This is the method that is called in step 2a. In this method, you may set up parameters, methods and attributes for your ObjectDataSource.

And here's some nice, friendly example code:

This is the InitGrid method that you will call from OnLoad, mentioned in step 2. This method should reside in your codebehind:

private void InitGrid()
{
odsSource = MyLibrary.MyNamespace.DataAccessClass.GetSource(m_intArg, m_blArg2);
odsSource.Selected += gvView_Selected;
odsSource.Deleting += gvView_Deleting;
odsSource.Deleted += gvView_Deleted;

this.Page.Controls.Add(odsSource);
this.gvView.DataSourceID = "odsSource";
}

And here is the GetSource() method mentioned in step 3. This method will reside in your data access class:

static public ObjectDataSource GetSource(int p_intArg, bool p_blArg2)
{
ObjectDataSource odsSource = new ObjectDataSource();

odsSource.ID = "odsSource";
odsSource.TypeName = "MyLibrary.MyNamespace.DataAccessClass";

odsSource.SelectMethod = "GetStuff";
odsSource.SelectParameters.Add(new Parameter("arg", TypeCode.Int32, p_intArg.ToString()));
odsSource.SelectParameters.Add(new Parameter("arg2", TypeCode.Boolean, p_blArg2.ToString()));

odsSource.DeleteMethod = "DeleteStuff";
odsSource.DeleteParameters.Add(new ControlParameter("stuffId", TypeCode.Int32, "gvView", "SelectedValue"));

return odsSource;
}

Share and enjoy!
 
Nice job!

One improvement you might be able to make, however, is to break the DAL class' coupling to ObjectDataSource and the GetSource() method. Because of GetSource() your code will break if ObjectDataSource goes away, and that shouldn't happen because your data access class should only be coupled to the entity it retrieves (for example, "EmployeeAccess" should only rely on the existance of "Employee").

If you encapsulated GetSource() inside a different adapter class (which can call the DAL class), then you break the coupling such that nuking ObjectDataSource won't break the entity DAL code (it will simply break the class that was coupled to the ObjectDataSource which is more expendible).

This is a more cohesive and resistant to failure if the underlying implmentation changes (say if you decide to use a list of entities rather than the ObjectDataSource).

That is assuming you want to go with a more traditional OO approach. :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top