p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   ASP.NET 2.0 Basics (http://p2p.wrox.com/forumdisplay.php?f=136)
-   -   HELP!!! (DropdownList in GridView question) (http://p2p.wrox.com/showthread.php?t=44431)

Aaron Edwards June 24th, 2006 09:36 AM

HELP!!! (DropdownList in GridView question)
 
I can't seem to get my DropDownList that's in a Gridview to hold onto it's selection (check it out at: http://www.scgis/org/ConferenceStore.aspx).

The GridView is based on a dataset that is created on the fly on the page's Load event.

The dropdown list is inside an Item template, and is declared and bound as follows:

                                    <asp:TemplateField HeaderText="Size" >

                                        <ItemTemplate>
                                          <asp:DropDownList ID="ddlSize" DataTextField="Size" DataValueField="Size" runat="server" DataSource='<%# PopulateControls(Eval("ProductName"))%>' >

                                          </asp:DropDownList>
                                        </ItemTemplate>

                                    </asp:TemplateField>

The PopulateControls method looks like this:

    Public Function PopulateControls(ByVal ProductName As String) As DataSet
        Dim cnxn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim da As New SqlDataAdapter
        Dim ds As New DataSet

        cnxn.ConnectionString = System.Configuration.ConfigurationManager.AppSetti ngs("ConnectionString")
        cnxn.Open()
        cmd.Connection = cnxn
        cmd.CommandText = "SELECT Size FROM tbl_SCGISMerchandise WHERE ProductName='" & ProductName & "'"
        da.SelectCommand = cmd

        da.Fill(ds, "Sizes")

        If ds.Tables(0).Rows(0)("Size").GetType Is System.Type.GetType("System.DBNull") Then
            Dim dr As DataRow = ds.Tables(0).NewRow
            dr("Size") = "N/A"
            ds.Tables(0).Rows.Add(dr)
        End If

        cmd.Dispose()
        da.Dispose()
        cnxn.Dispose()

        Return ds
    End Function

Since the dropdown is active for all items in the grid, and not just when in edit mode, I attempt to save the contents of the dropdown as follows:

            'go through gridview and save all sizes to dataset so we don't lose them
            Dim i As Integer = 0
            For Each gvr As GridViewRow In Me.gvCart.Rows
                Dim DDL As DropDownList = CType(gvr.FindControl("ddlSize"), DropDownList)
                Dim selectedItem As ListItem = DDL.SelectedItem
                Dim selectedValue As String = selectedItem.Value
                dsItemsOrdered.Tables(0).Rows(i)("Size") = selectedValue
                i += 1
            Next
            dsItemsOrdered.AcceptChanges()

(This is inside the RowCommand event of the other data grid on that page).

As you can see by checking it out live, what's happenning is that it's not returning the selectedItem from the dropdown list, but rather the first item in the list.

Please help ASAP. This thing is due in a few hours.

Thanks!

Aaron



rrmarriott June 24th, 2006 12:55 PM

Aaron,

Inside you RowCommand event, you are calling AcceptChanges on your DataSet. This saves changes in the disconnected DataSet, but not actually to the underlying database itself. Because of this when the page reloads, the DataSet will be just reloaded from the original data in the database, rather than displaying any chages you made.

Is this your problem, or have have I misunderstood you? Your online demo doesn't have the DropDowns anymore (as far as I can see) so i'm not fully sure of the behaviour that you are experiencing.:)

Rich


Aaron Edwards June 24th, 2006 02:04 PM

Hi Rich,

Thanks for the reply.

This dataset is created on the fly, and has no underlying datastore from a database. I'm persisting it across posts with a Session variable. I've tried it both with and withoug the AcceptChanges method, nothing's working yet. Right now its up there without (since your post I commented it out).

The dropdowns should now be working. You need to click an "Add to Cart" button to see it appear.

Thanks!


Aaron Edwards June 24th, 2006 02:09 PM

I forgot to mention. In order to see the problem manifast, you need to

(1) click one of the "Add to Cart" buttons
(2) in the Cart panel, change the dropdown
(3) click another "Add to Cart" button

The value that you changed in the dropdown goes back to its default.

Thanks!


rrmarriott June 24th, 2006 06:31 PM

Aaron,

After you postback each time, are you actually resetting the selected value of the drop down list? I can't see anywhere in your code that is doing this (however I do assume that all your code is not in this post).

To ensure that the correct value is set after each postback you should use the RowDataBound event of the GridView and find the ddlSize control, setting its selected value from the value you are persisting in your DataSet.

As I said, I don't know whether you have done this already, but haven't included the code in your post.

Hope this helps,
Rich


Aaron Edwards June 24th, 2006 08:36 PM

Well actually Rich that helps a lot. It tells me that I need to switch my approach from inline databinding to an event-driven model. I'll post all my code if I don't get it working in the next hour or so, but thank you.


Aaron Edwards June 24th, 2006 09:38 PM

Hi Rich,

Well you're right, I never acutally set the selectedValue of the dropdown. Duh! I think I tried to do it declaratively, but it wouldn't let me, not sure why not. So I guess I need to do it in code, which I'll do in the RowDataBound event as you suggested. I'll let you know how it works.

Aaron


Aaron Edwards June 25th, 2006 12:16 AM

Hold on a minute! I just had a revalation! What I want to do is not to SET the dropdown with a value from my dataset. I want to GET the SelectedVAlue FROM my drowpdown so I can put it INTO my dataset!

I think my problem is stemming from the fact that I have the dropdown in an ItemTemplate instead of an EditItemTemplate. Since I literally have a dropdown for the Size column in every single row, I run this code whenever I'm about to re-bind the datagrid:

            'go through gridview and save all sizes to dataset so we don't lose them
            Dim i As Integer = 0
            For Each gvr As GridViewRow In Me.gvCart.Rows
                Dim DDL As DropDownList = CType(gvr.FindControl("ddlSize"), DropDownList)
                Dim selectedItem As ListItem = DDL.SelectedItem
                Dim selectedValue As String = selectedItem.Value
                dsItemsOrdered.Tables(0).Rows(i)("Size") = selectedValue
                i += 1
            Next
            'dsItemsOrdered.AcceptChanges()

(You can see where I remmed out my AcceptChanges method).

Basically I need to manually update the dataset, because it's not happenning automatically.



Aaron Edwards June 25th, 2006 01:32 AM

Okay, I have this figured out now. And basically, it cannot be solved.

I'm kind of thinking out loud here. Basically, the problem stemmed from the fact that the act of databinding the dropdown erases the selected selectedValue that it once had. Usually, after binding, one would populate it's selectedValue with a value from the datastore, in this case a dataset. But since this dropdown is in an ItemTemplate, rather than an EditItemTemplate, changes in its value are not automatically saved in the underlying dataset.

One guy (http://webthingsconsidered.blogspot....idview-or.html) solves this by only doing the binding if isPostback is not true. This is a great approach for most applications, but in my case the gridView is only populated in the first place in response to a Postback.

If there were some way to determine if a dropdown in a row had already once been databound, or if the row itself were new, that would do the trick, but I don't think there is.

Aaron


Aaron Edwards June 25th, 2006 03:34 AM

Still doesn't work. I'm doing standard editing now and it still reverts back to the old value, even for the textbox (Quantity) field. I'm goihg to post my whole source code in hope that some superhero will fly down and save me (Your cue, Imar).

<%@ Page Language="VB" MasterPageFile="~/MerchDB.master" AutoEventWireup="false" CodeFile="ConferenceStore.aspx.vb" Inherits="ConferenceStore" title="SCGIS - Store" %>

<%@ Register Assembly="AtlasControlToolkit" Namespace="AtlasControlToolkit" TagPrefix="cc1" %>
<%@ MasterType VirtualPath="~/MerchDB.master" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="font-family: Verdana, Sans-Serif;">
<atlas:ScriptManager ID="sm" runat="server" EnablePartialRendering="true"></atlas:ScriptManager>
    <table>
        <tr>
            <td width=540 valign="top">
               <atlas:UpdatePanel ID="UP1" Mode="Conditional" runat="server">
                <ContentTemplate>
                    <asp:GridView DataKeyNames="pkProductID" ID="gvMerchandise" runat="server" AlternatingRowStyle-BackColor="Beige" GridLines="Horizontal" AllowSorting="True" AutoGenerateColumns="False" DataSourceID="ObjectDataSource2" Width="540px" BackColor="White" BorderColor="#336666" BorderStyle="Double" BorderWidth="3px" CellPadding="4" EditRowStyle-Width="100px" EmptyDataRowStyle-Width="100px" PageSize="6" Font-Size="8pt">
                        <Columns>
                            <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" ItemStyle-Width="100"/>
                            <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" ItemStyle-Width="160" />
                            <asp:BoundField DataField="Price" DataFormatString="{0:C}" HtmlEncode="false" HeaderText="Price" SortExpression="Price" ItemStyle-Width="60"/>
                            <asp:ImageField DataImageUrlField="ImageName">
                                <ControlStyle Width="80px" />
                                <ItemStyle Width="80px" />
                            </asp:ImageField>
                            <asp:ButtonField CommandName="AddToCart" Text="Add to Cart" ItemStyle-Width="80" />
                        </Columns>
                        <FooterStyle BackColor="White" ForeColor="#333333" />
                        <RowStyle BackColor="White" ForeColor="#333333" />
                        <SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
                        <PagerStyle BackColor="#336666" ForeColor="White" HorizontalAlign="Center" />
                        <HeaderStyle BackColor="#203738" Font-Bold="True" ForeColor="White" />
                        <AlternatingRowStyle BackColor="Beige" />
                        <EmptyDataRowStyle Width="100px" />
                        <EditRowStyle Width="100px" />
                    </asp:GridView>
                </ContentTemplate>

                </atlas:UpdatePanel>


            </td>
            <td valign=top width=200>

                <cc1:AlwaysVisibleCont********************tender ID="AlwaysVisibleCont********************tender1" runat="server">
                <cc1:AlwaysVisibleControlProperties TargetControlID="divCart" HorizontalSide="Left" HorizontalOffset="680" VerticalOffset="10" ScrollEffectDuration=".1" />
                </cc1:AlwaysVisibleCont********************tender>
                <div ID="divCart" runat="server" style="Position:absolute; top: 10px; border: 1px black solid; width: 360px; left: 680px; background-color: GhostWhite;">
                    <div style="margin-top: 0px; font-size: 10pt; font-weight:bold; " align="center">Shopping Cart</div>
                    <atlas:UpdatePanel ID="UP3" runat="server" Mode="Conditional">
                        <ContentTemplate>
                            <asp:GridView ID="gvCart" DataKeyNames="pkCartItemID" runat="server" AutoGenerateColumns="False" Width="360px" AlternatingRowStyle-BackColor="Cornsilk" HeaderStyle-BackColor="#203738" HeaderStyle-ForeColor="White">
                                <Columns>

                                    <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
                                    <asp:BoundField DataField="ProductName" HeaderText="Item Name" ReadOnly = "True" />
                                    <asp:TemplateField HeaderText="Size">
                                        <EditItemTemplate>
                                            <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Size") %>'></asp:TextBox>
                                        </EditItemTemplate>
                                        <ItemTemplate>
                                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("Size") %>'></asp:Label>
                                        </ItemTemplate>
                                        <ControlStyle Width="80px" />
                                    </asp:TemplateField>
                                    <asp:BoundField DataField="UnitPrice" ReadOnly="True" HeaderText="Price" DataFormatString="{0:C}" HtmlEncode="False"/>
                                    <asp:TemplateField HeaderText="Qty.">
                                        <EditItemTemplate>
                                            <asp:TextBox ID="tbQty" runat="server" Text='<%# Bind("Quantity") %>'></asp:TextBox>
                                        </EditItemTemplate>
                                        <ControlStyle Width="30px" />
                                        <ItemStyle HorizontalAlign="Center" />
                                        <ItemTemplate>
                                            <asp:Label ID="Label2" runat="server" Text='<%# Bind("Quantity") %>'></asp:Label>
                                        </ItemTemplate>
                                    </asp:TemplateField>
                                    <asp:BoundField DataField="ExtendedPrice" ReadOnly="True" HeaderText="Ext. Price" DataFormatString="{0:C}" HtmlEncode="False" />
                                    <asp:CheckBoxField DataField="booPerk" HeaderText="Free Perk?" />

                                </Columns>
                                <RowStyle Font-Size="8pt" />
                                <HeaderStyle Font-Names="verdana,sans-serif" Font-Size="8pt" BackColor="#203738" ForeColor="White" />
                                <AlternatingRowStyle BackColor="Cornsilk" />
                            </asp:GridView>

                            <div align="center">
                                <asp:Label ID="lblCartEmpty" runat="server" Visible=False Font-Bold="true" Font-Size="8"><br>Empty<br></asp:Label>
                            </div>
                            <div id="divButtons" runat="server" style="visibility: hidden;">
                                <table width="360">
                                    <tr>
                                        <td align="left">
                                            <asp:Button id="btnEmptyCart" runat="server" Text="Empty Cart" />
                                        </td>
                                        <td align="right">
                                            <asp:Button id="btnCheckout" runat="server" Text="Checkout" />
                                        </td>
                                    </tr>
                                </table>
                            </div>


                        </ContentTemplate>
                        <Triggers>
                            <atlas:ControlEventTrigger ControlID="gvMerchandise" EventName="RowCommand" />
                        </Triggers>
                    </atlas:UpdatePanel>

                </div>
            </td>
        </tr>
    </table>

        <asp:ObjectDataSource ID="ObjectDataSource2" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetData"
        TypeName="dsMerch2TableAdapters.tbl_SCGISMerchandi seTableAdapter">
    </asp:ObjectDataSource>



</div>
</asp:Content>



Codebehind now

Imports System.Data
Imports System.Data.SqlClient

Partial Class ConferenceStore
    Inherits System.Web.UI.Page

    Dim dsItemsOrdered As New DataSet

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            'Session("dssItemsOrdered") = Nothing
            'Session("dsItemsOrdered") = Nothing
            'Session("Invoice") = Nothing
            'Session("GrandTotal") = Nothing
            'Session("CartDetailsHTML") = Nothing
            'Session("CartDetailsText") = Nothing

        End If

        If Not Session("MerchLoggedIn") = True Then
            'Response.Redirect("MerchLogin.aspx?ReturnPath=Mer chDatabase.aspx")
        End If

        'Create OrderItem dataset if it doesn't exist already
        'if it does exist, load from Session

        If Session("dssItemsOrdered") Is Nothing Then

            dsItemsOrdered.Tables.Add("ItemsOrdered")
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "pkCartItemID", System.Type.GetType("System.Int16"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns(0).A utoIncrement = True
            dsItemsOrdered.Tables("ItemsOrdered").Columns(0).A utoIncrementSeed = 1
            dsItemsOrdered.Tables("ItemsOrdered").Columns(0).A utoIncrementStep = 1

            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "ProductID", System.Type.GetType("System.Int16"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "ProductName", System.Type.GetType("System.String"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "Size", System.Type.GetType("System.String"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "UnitPrice", System.Type.GetType("System.Single"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "Quantity", System.Type.GetType("System.Int16"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "ExtendedPrice", System.Type.GetType("System.Single"))
            dsItemsOrdered.Tables("ItemsOrdered").Columns.Add( "booPerk", System.Type.GetType("System.Boolean"))



            'Store dataset in session
            Dim stream As New System.IO.StringWriter
            dsItemsOrdered.WriteXml(stream, XmlWriteMode.DiffGram)
            Session("dsItemsOrdered") = stream
            Session("dssItemsOrdered") = dsItemsOrdered.GetXmlSchema
        Else

            'get xml back from Session
            Dim sr As New System.IO.StringReader(Session("dsItemsOrdered").T oString)
            Dim srr As New System.IO.StringReader(Session("dssItemsOrdered"))
            dsItemsOrdered.ReadXmlSchema(srr)
            dsItemsOrdered.ReadXml(sr)

        End If

        Me.gvCart.DataSource = dsItemsOrdered
        Me.gvCart.DataMember = "ItemsOrdered"
        Me.gvCart.DataBind()

        If dsItemsOrdered.Tables(0).Rows.Count <= 0 Then
            Me.lblCartEmpty.Visible = True
            divButtons.Style.Item("visibility") = "hidden"
        Else
            Me.lblCartEmpty.Visible = False
            divButtons.Style.Item("visibility") = "visible"
        End If
    End Sub

    Protected Sub gvCart_Editing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) Handles gvCart.RowEditing
        gvCart.EditIndex = e.NewEditIndex
        DataBind()
    End Sub

    Protected Sub gvCartEditing_Canceling(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs) Handles gvCart.RowCancelingEdit
        gvCart.EditIndex = -1
        DataBind()
    End Sub

    Protected Sub gvCart_Updating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs) Handles gvCart.RowUpdating
        Dim row As GridViewRow = gvCart.Rows(e.RowIndex)
        If Not row Is Nothing Then
            Dim tb As TextBox = CType(row.FindControl("tbQty"), TextBox)
            Dim dr As DataRow = dsItemsOrdered.Tables(0).Rows(e.RowIndex)
            dr("Quantity") = tb.Text

            'Store dataset in session
            Dim stream As New System.IO.StringWriter
            dsItemsOrdered.WriteXml(stream, XmlWriteMode.DiffGram)
            Session("dsItemsOrdered") = stream
            Session("dssItemsOrdered") = dsItemsOrdered.GetXmlSchema

        End If

        gvCart.EditIndex = -1
        'DataBind()
    End Sub

    Protected Sub gvMerchandise_Command(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) Handles gvMerchandise.RowCommand
        If e.CommandName = "AddToCart" Then

            'Get reference to the row being clicked on
            Dim index As Integer = e.CommandArgument
            Dim ItemID As Integer = gvMerchandise.DataKeys(index).Value
            Dim dr As DataRow = dsItemsOrdered.Tables(0).NewRow
            dr("ProductID") = ItemID
            dr("ProductName") = Me.gvMerchandise.Rows(index).Cells(0).Text
            Try
                dr("UnitPrice") = Me.gvMerchandise.Rows(index).Cells(2).Text.Substri ng(1)
            Catch ex As Exception

            End Try

            dr("Quantity") = 1
            Try
                dr("ExtendedPrice") = Single.Parse(dr("UnitPrice")) * Int16.Parse(dr("Quantity"))
            Catch ex As Exception

            End Try

            dr("booPerk") = False

            dsItemsOrdered.Tables(0).Rows.Add(dr)

            If dsItemsOrdered.Tables(0).Rows.Count <= 0 Then
                Me.lblCartEmpty.Visible = True
                divButtons.Style.Item("visibility") = "hidden"
            Else
                Me.lblCartEmpty.Visible = False
                divButtons.Style.Item("visibility") = "visible"
            End If


            'Store dataset in session
            Dim stream As New System.IO.StringWriter
            dsItemsOrdered.WriteXml(stream, XmlWriteMode.DiffGram)
            Session("dsItemsOrdered") = stream
            Session("dssItemsOrdered") = dsItemsOrdered.GetXmlSchema

            Me.gvCart.DataBind()


        End If
    End Sub

    Protected Sub btnEmptyCart_Click1(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEmptyCart.Click
        Session("dssItemsOrdered") = Nothing
        dsItemsOrdered.Tables(0).Clear()
        Me.gvCart.DataBind()

        If dsItemsOrdered.Tables(0).Rows.Count <= 0 Then
            Me.lblCartEmpty.Visible = True
            divButtons.Style.Item("visibility") = "hidden"
        Else
            Me.lblCartEmpty.Visible = False
            divButtons.Style.Item("visibility") = "visible"
        End If

    End Sub

    Protected Sub btnCheckout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCheckout.Click

        'go through gridview and save all sizes to dataset so we don't lose them
        Dim i As Integer = 0
        For Each gvr As GridViewRow In Me.gvCart.Rows
            Dim DDL As DropDownList = CType(gvr.FindControl("ddlSize"), DropDownList)
            Dim selectedItem As ListItem = DDL.SelectedItem
            Dim selectedValue As String = selectedItem.Value
            dsItemsOrdered.Tables(0).Rows(i)("Size") = selectedValue
            i += 1
        Next
        dsItemsOrdered.AcceptChanges()

        'Store dataset in session
        Dim stream As New System.IO.StringWriter
        dsItemsOrdered.WriteXml(stream, XmlWriteMode.DiffGram)
        Session("dsItemsOrdered") = stream
        Session("dssItemsOrdered") = dsItemsOrdered.GetXmlSchema

        Response.Redirect("ConferenceStoreCheckout.aspx")
    End Sub

    Public Function GetSizes(ByVal ProductName As String) As DataSet
        Dim cnxn As New SqlConnection
        Dim cmd As New SqlCommand
        Dim da As New SqlDataAdapter
        Dim ds As New DataSet

        cnxn.ConnectionString = System.Configuration.ConfigurationManager.AppSetti ngs("ConnectionString")
        cnxn.Open()
        cmd.Connection = cnxn
        cmd.CommandText = "SELECT Size FROM tbl_SCGISMerchandise WHERE ProductName='" & ProductName & "'"
        da.SelectCommand = cmd

        da.Fill(ds, "Sizes")

        If ds.Tables(0).Rows(0)("Size").GetType Is System.Type.GetType("System.DBNull") Then
            Dim dr As DataRow = ds.Tables(0).NewRow
            dr("Size") = "N/A"
            ds.Tables(0).Rows.Add(dr)
        End If

        cmd.Dispose()
        da.Dispose()
        cnxn.Dispose()

        Return ds
    End Function

    Protected Sub RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvCart.RowDataBound


    End Sub
End Class




All times are GMT -4. The time now is 11:19 PM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.