Solved

How to handle update event of a gridview bound to a generic collection

Posted on 2008-10-14
11
277 Views
Last Modified: 2008-10-15
HI Guys

Considering 3 tier model I have developed a class (BLL) that its instance must be bound to a gridview, so everything is fine except for the fact that I don´t know how to handle UPDATE event considering that the data is not editable by a SQL command/sentence.

Thanks in advance.
0
Comment
Question by:dimensionav
  • 6
  • 5
11 Comments
 
LVL 18

Expert Comment

by:David Robitaille
Comment Utility
Use a ObjectDataSource
Use  <UpdateParameters>
if you have complex stuff to do, do i in the gridview ItemInserting event, in that event you could use
e.Values("parameter name") = myvalue
to set a parameter value

0
 
LVL 18

Expert Comment

by:David Robitaille
Comment Utility
What are you trying to do in your update and what is problematic?
How did you "bind" your instance to your gridview?
 
0
 

Author Comment

by:dimensionav
Comment Utility
HI davrob60

I haven´t tried anything, I just prefered to wait for your answer, my imagination is not working at this point (I have 2 nights without sleeping, ha).

I am using an ObjectDataSource like this:

            <asp:ObjectDataSource id="odsCarrito" runat="server"
                                  TypeName="DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLCarritoDeCompras"
                                  SelectMethod="ObtieneContenidoDeCarrito">
                <SelectParameters>
                    <asp:Parameter Name="CurrentSession" Type="Object"  />
                </SelectParameters>
            </asp:ObjectDataSource>

And I got successfuly an instance of the following class:

Imports System.Web
Imports System.Data
Imports System.Data.OleDb
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Collections.Generic
Imports DAV.TiendaEnLinea.v1.DataAccessLayer

Namespace DAV.TiendaEnLinea.v1.BusinessLogicLayer
    Public Class BLLCarritoDeCompras

        Private _Cantidad As Integer = 0
        Private _Id_Producto As Integer = 0
        Private _Codigo As String = String.Empty
        Private _NumeroParte As String = String.Empty
        Private _Titulo As String = String.Empty
        Private _PrecioLista As String = String.Empty
        Private _PrecioPromocion As String = String.Empty
        Private _ImagenMini As String = String.Empty
        Private _ImagenReal As String = String.Empty

        Public Property Cantidad() As Integer
            Get
                Return _Cantidad
            End Get
            Set(ByVal Value As Int32)
                _Cantidad = Value
            End Set
        End Property

        Public ReadOnly Property Id_Producto() As Integer
            Get
                Return _Id_Producto
            End Get
        End Property

        Public ReadOnly Property Codigo() As String
            Get
                Return _Codigo
            End Get
        End Property

        Public ReadOnly Property NumeroParte() As String
            Get
                Return _NumeroParte
            End Get
        End Property

        Public ReadOnly Property Titulo() As String
            Get
                Return _Titulo
            End Get
        End Property

        Public ReadOnly Property PrecioLista() As Double
            Get
                Return _PrecioLista
            End Get
        End Property

        Public ReadOnly Property PrecioPromocion() As Double
            Get
                Return _PrecioPromocion
            End Get
        End Property

        Public ReadOnly Property ImagenMini() As String
            Get
                Return _ImagenMini
            End Get
        End Property

        Public ReadOnly Property ImagenReal() As String
            Get
                Return _ImagenReal
            End Get
        End Property
        Public Shared Function ObtieneContenidoDeCarrito(ByRef CurrentSession As DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLSessionManager) As List(Of BLLCarritoDeCompras)
            Return CurrentSession.CarritoDeCompras
        End Function


        Public Sub New(ByVal cantidad As Integer, ByVal id_producto As Integer, ByVal codigo As String, _
                       ByVal numeroparte As String, ByVal titulo As String, _
                       ByVal preciolista As Double, ByVal preciopromocion As Double, _
                       ByVal imagenmini As String, ByVal imagenreal As String)

            'Inicializa las propiedades del objeto
            _Cantidad = cantidad
            _Id_Producto = id_producto
            _Codigo = codigo
            _NumeroParte = numeroparte
            _Titulo = titulo
            _PrecioLista = preciolista
            _PrecioPromocion = preciopromocion
            _ImagenMini = imagenmini
            _ImagenReal = imagenreal

        End Sub

    End Class
End Namespace


And the following GridView is perfectly populated:

            <asp:GridView runat="server"
                ID="gvProductos"
                AutoGenerateColumns="False"
                HeaderStyle-CssClass="Negro12B" RowStyle-CssClass="Lila12N" CellPadding="5"
                AllowSorting="True"
                DataSourceID="odsCarrito"
                DataKeyNames="Id_Producto"
                ShowFooter="true">
                <columns>
                    <asp:BoundField DataField="Cantidad" HeaderText="CANTIDAD" SortExpression="CANTIDAD"></asp:BoundField>
                    <asp:BoundField DataField="Codigo" HeaderText="CODIGO" SortExpression="MODELO"  ></asp:BoundField>
                    <asp:BoundField DataField="Titulo" HeaderText="DESCRIPCION" SortExpression="DESCRIPCION"></asp:BoundField>
                    <asp:BoundField DataField="PrecioLista" HeaderText="PRECIO" SortExpression="PRECIO" HtmlEncode="false" DataFormatString="{0:C2}" ItemStyle-HorizontalAlign="Right"></asp:BoundField>

                    <asp:TemplateField HeaderText="SUBTOTAL" SortExpression="SUBTOTAL" ItemStyle-HorizontalAlign="Right">
                        <ItemTemplate>
                          <asp:Label ID="lbSubtotal" Runat="Server"
                                     Text='<%# String.Format("{0:C2}", Eval("Cantidad") * Eval("PrecioLista")) %>' />
                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:CommandField CancelText="Cancelar" DeleteText="Eliminar" EditText="Cambiar Cantidad"
                        ShowCancelButton="False" ShowDeleteButton="True" ShowEditButton="True" />
                </columns>
                <RowStyle CssClass="Lila12N" />
                <HeaderStyle CssClass="Negro12B" />
                <EmptyDataTemplate>
                    <span class="NegroN12">
                        ! Por el momento tu carrito de compras aparece vacío ¡ <br /><br />
                        Si deseas agregar productos ingresa al CATALOGO.<br /><br />
                        Si no tienes cuenta o no has iniciado sesion ingresa a TU CUENTA para mas detalles.
                       
                    </span>
              </EmptyDataTemplate>
            </asp:GridView>

Thanks in advance
0
 
LVL 18

Expert Comment

by:David Robitaille
Comment Utility
  1. Get some sleep. ;-)
  2. It s not a usual way of doing a BLL. The BLL should be you interface between the datalayer and the web page. the way you did it (more particulary the session object) seem odd to me
  3. You should write a BLL function that will update your bll object. each parameter of that sub should be "linked" ot a parameter in the ObjectDataSource update parameter. the object datasource will call the UpdateMethod you specify and pass the parameters. as an exemple, since you have as  <asp:BoundField DataField="Codigo", you could set a update parameter named Codigo, the GridView will pass the field value to the ObjectDataSource Codigo parameter that will pass it tou the sub set in it`s UpdateMethod of the BLLCarritoDeCompras class. it<s that method that will do the update, as an exemple, build a sql update query or call a datalayer objec that will do that job.
i hope this will be helpfull
 
 
0
 

Author Comment

by:dimensionav
Comment Utility
1. Done...Ha
2.You´re right and that is because, as a part of the architecure of my website, I always pass an object called CurrentSession (which contains all the session configurations), but this case I believe is kind of weird because I am passing the object from and to the same layer (BLL), perhaps it shouldn´t be but Im trying to mantain the "communication logic" between layers.
3. Everything seems clear to me except for the fact that you say that I should call SQL statement, I am using a generic collection (BLLCarritoDeCompras) instead of a table.

You said that I should use <UpdateParameters> , like this:
e.Values("parameter name") = myvalue

I assume e.Values("parameter name") is the old value, am I right?, how could I identify the new value changed by the user, in order to do something like:

e.Values("parameter name") = newvalue


Thanks again
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 18

Expert Comment

by:David Robitaille
Comment Utility
i was talking about the SQL statement because it`s a frequent datasource. if it`s a generic collection, then your method should update the Private _ variable of the object.
the "e.Values("parameter name") = myvalue" is user only if you need to compute thing before setting them (exemple, e.Values("total")= price+taxes ). e.Values("parameter name") just transfer the value to the updateMethod. if you dont have things to compute, the GridView will forward values to the updateMethod if the parameter name matches the DataField name.
You dont have to identify the values changed by the user, just forward all to the updateMethod.

 
0
 

Author Comment

by:dimensionav
Comment Utility
HI davrob60

I got the following error : No parameterless constructor defined for this object

This is the new update method:

        Public Sub ActualizaContenidoDeCarrito(ByVal Cantidad As Integer, ByVal Id_Producto As Integer)
            _Cantidad = Cantidad
            _Id_Producto = Id_Producto

        End Sub

And there are the GridView and ObjectDataSource (Notice the DataKeyNames and the New Parameters):

            <asp:GridView runat="server"
                ID="gvProductos"
                AutoGenerateColumns="False"
                HeaderStyle-CssClass="Negro12B" RowStyle-CssClass="Lila12N" CellPadding="5"
                AllowSorting="True"
                DataSourceID="odsCarrito"
                DataKeyNames="Id_Producto"
                ShowFooter="true">
                <columns>
                    <asp:BoundField DataField="Id_Producto" ReadOnly="true"></asp:BoundField>
                    <asp:BoundField DataField="Cantidad" HeaderText="CANTIDAD" SortExpression="CANTIDAD"></asp:BoundField>
                    <asp:BoundField DataField="Codigo" HeaderText="CODIGO" SortExpression="MODELO" ReadOnly="true"  ></asp:BoundField>
                    <asp:BoundField DataField="Titulo" HeaderText="DESCRIPCION" SortExpression="DESCRIPCION" ReadOnly="true"></asp:BoundField>
                    <asp:BoundField DataField="PrecioLista" HeaderText="PRECIO" SortExpression="PRECIO" ReadOnly="true" HtmlEncode="false" DataFormatString="{0:C2}" ItemStyle-HorizontalAlign="Right"></asp:BoundField>

                    <asp:TemplateField HeaderText="SUBTOTAL" SortExpression="SUBTOTAL" ItemStyle-HorizontalAlign="Right">
                        <ItemTemplate>
                          <asp:Label ID="lbSubtotal" Runat="Server"
                                     Text='<%# String.Format("{0:C2}", Eval("Cantidad") * Eval("PrecioLista")) %>' />
                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:CommandField CancelText="Cancelar" DeleteText="Eliminar" EditText="Cambiar Cantidad"
                        ShowCancelButton="False" ShowDeleteButton="True" ShowEditButton="True" />
                </columns>
                <RowStyle CssClass="Lila12N" />
                <HeaderStyle CssClass="Negro12B" />
                <EmptyDataTemplate>
                    <span class="NegroN12">
                        <% 'DeshabilitaLinks() %>
                        ! Por el momento tu carrito de compras aparece vacío ¡ <br /><br />
                        Si deseas agregar productos ingresa al CATALOGO.<br /><br />
                        Si no tienes cuenta o no has iniciado sesion ingresa a TU CUENTA para mas detalles.
                       
                    </span>
              </EmptyDataTemplate>
 
            </asp:GridView>

            <asp:ObjectDataSource id="odsCarrito" runat="server"
                                  OnSelecting="odsProductos_Selecting"
                                  TypeName="DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLCarritoDeCompras"
                                  SelectMethod="ObtieneContenidoDeCarrito"
                                  UpdateMethod="ActualizaContenidoDeCarrito">
                <SelectParameters>
                    <asp:Parameter Name="CurrentSession" Type="Object"  />
                </SelectParameters>

            <UpdateParameters>
                <asp:Parameter Type="int32" Name="Cantidad"></asp:Parameter>
            </UpdateParameters>
               
            </asp:ObjectDataSource>
0
 
LVL 18

Expert Comment

by:David Robitaille
Comment Utility
well it<s because of you sesion stuff...
For what i understand of your code, you update method should be Public Shared Function and also have a "ByRef CurrentSession As DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLSessionManager" like the select method. that parameter should also be set ObjectDataSource update like for the select method
the problem is the ObjectDataSource try to create a brand new BLLCarritoDeCompras, but return a error since the class dont have a Public Sub New() witout parameter. i guess the best is to retrive the one in your session instead or creatin a new one...
0
 

Author Comment

by:dimensionav
Comment Utility
       Public Shared Function ObtieneContenidoDeCarrito(ByRef CurrentSession As DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLSessionManager) As List(Of BLLCarritoDeCompras)
            Return CurrentSession.CarritoDeCompras
        End Function

        Public Sub ActualizaContenidoDeCarrito(ByVal Cantidad As Integer, ByVal Id_Producto As Integer)
            _Cantidad = Cantidad
            _Id_Producto = Id_Producto
        End Sub

As you could see I took a reference to SessionManager.CarritoDeCompras to populate de GridView
would be possible to update first the session instance and after that bound it again to the GridView?

Thanks
0
 
LVL 18

Accepted Solution

by:
David Robitaille earned 250 total points
Comment Utility
something like this, the only problem is that CarritoDeCompras seem to be a list, so you have to retrive the object before, but you should get the point...
Public Shared Sub ActualizaContenidoDeCarrito(ByRef CurrentSession As DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLSessionManager, ByVal Cantidad As Integer, ByVal Id_Producto As Integer)
                     
                      CurrentSession.CarritoDeCompras.update(Cantidad, Id_Producto  )

        End Sub
Public Sub update(ByVal Cantidad As Integer, ByVal Id_Producto As Integer)
            _Cantidad = Cantidad
            _Id_Producto = Id_Producto
        End Sub

0
 

Author Comment

by:dimensionav
Comment Utility
It worked!

Just some considerations:

1. As you said before CarritoDeCompras is a custom class (instance of BLLCarritoDeCompras), which is a property part of the SessionManager object that contains the list of the products of the shopping cart, that´s the reason why that list must be associated to each user session.

2. I needed to use its method Item(n)

Here is the method:

        Public Shared Sub ActualizaContenidoDeCarrito(ByRef CurrentSession As DAV.TiendaEnLinea.v1.BusinessLogicLayer.BLLSessionManager, ByVal Id_Producto As Integer, ByVal Cantidad As Integer)
            For n As Integer = 0 To (CurrentSession.CarritoDeCompras.Count - 1)
                If CurrentSession.CarritoDeCompras.Item(n).Id_Producto = Id_Producto Then
                    CurrentSession.CarritoDeCompras.Item(n).Cantidad = Cantidad
                    Exit For
                End If
            Next
        End Sub
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Today is the age of broadband.  More and more people are going this route determined to experience the web and it’s multitude of services as quickly and painlessly as possible. Coupled with the move to broadband, people are experiencing the web via …
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now