0

Follow on from this thread.

Basically, I have a GridView which displays data pulled from a database, and the page also has a filter button such that clicking on a staff member on the list will change the SQL statement so that only that staff member is selected.

Within the GridView each row has a button which in essence exports the AppointmentID to a variable so further information can be shown.

However, once the filter button is pressed and the GridView contents changes the buttons in the GridView no longer 'exports' the correct ID.

Markup for the filter button:

<div class="dropdown"> 
    <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"  id="dropdownstaff"><asp:Label runat="server" ID="lblDropdownstaff" Text="All Stylists"></asp:Label>
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" id="ulStaffSelect">
        <li><asp:Button runat="server" Text="All Stylists" ID="lstStaffSelect1"/></li>
        <li><asp:Button runat="server" Text="Elaine" ID="lstStaffSelect2"/></li>
        <li><asp:Button runat="server" Text="Dawn" ID="lstStaffSelect3"/></li>
    </ul>
</div>

Markup for the GridView (Note the commented out LinkedButton - It behaves the same as my normal button does with "UseSubmitBehaviour" set to false):

<asp:GridView ID="Staffgv" runat="server" AutoGenerateColumns="false" AllowPaging="true" PageSize="20" OnPageIndexChanging="Staffgv_PageIndexChanging" BackColor="#f9f9f9" CssClass="gvStyle" OnRowCommand="Staffgv_RowCommand">
    <HeaderStyle CssClass="gvHeadStyle" />
    <PagerSettings  Mode="NextPreviousFirstLast" FirstPageText="<<" PreviousPageText="<" NextPageText=">" LastPageText=">>" />
    <AlternatingRowStyle BackColor="#ffffff"  CssClass="gvAlternatingClass"/>
    <Columns>
        <asp:TemplateField HeaderText="Start" InsertVisible="False" SortExpression="DateTimeStart">
            <HeaderStyle Width="70px"   CssClass="hdrGvStart"/>
            <ItemTemplate>
                <asp:Label ID="lblDateTimeStart" runat="server" Text='<%# Bind("DateTimeStart", "{0:t}") %>'></asp:Label>
            </ItemTemplate>      
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Finish" SortExpression="DateTimeEnd">
            <HeaderStyle Width="70px"   CssClass="hdrGvFinish"/>
            <ItemTemplate>
                <asp:Label ID="lblDateTimeEnd" runat="server" Text='<%# Bind("DateTimeEnd", "{0:t}") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Forename" SortExpression="Forename">
            <HeaderStyle Width="140px"  CssClass="hdrGvForename"/>
            <ItemTemplate>
                <asp:Label ID="lblForename" runat="server" Text='<%# Bind("Forename") %>'></asp:Label>
            </ItemTemplate>               
        </asp:TemplateField>  
        <asp:TemplateField HeaderText="Surname" SortExpression="Surname">
            <HeaderStyle Width="140px"   CssClass="hdrGvSurname"/>
            <ItemTemplate>
                <asp:Label ID="lblSurname" runat="server" Text='<%# Bind("Surname") %>'></asp:Label>
            </ItemTemplate>               
        </asp:TemplateField>                                              
        <asp:TemplateField>
            <HeaderStyle CssClass="gvHeaderEdit" />
            <ItemTemplate>
                <asp:Button ID="Btnapptid" runat="server" Text="____"  CssClass="btnGVEdit" CommandName="FillStaffTables" CommandArgument='<%# Bind("AppointmentID") %>' UseSubmitBehavior="false"/>
                <%--<asp:LinkButton ID="Btnapptid" runat="server" Text="____"  CssClass="btnGVEdit" CommandName="FillStaffTables" CommandArgument='<%# Bind("AppointmentID") %>'  Width="48px" Height="48px"/>--%>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

And the VB code:

Dim connString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='C:\Users\me\Documents\Visual Studio 2015\Datebases\DB.mdf';Integrated Security=True;Connect Timeout=30"

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    lblStaffHead.Text = "You are logged in as " & StaffMemberName
    selectedStaffMember = "Salon"
    generatePage(selectedStaffMember)
End Sub

Protected Sub lstStaffSelect1_Click(ByVal sender As Object, e As EventArgs) Handles lstStaffSelect1.Click
    lblDropdownstaff.Text = "All Stylists"
    selectedStaffMember = "Salon"

    generatePage(selectedStaffMember)
End Sub

Protected Sub lstStaffSelect2_Click(ByVal sender As Object, e As EventArgs) Handles lstStaffSelect2.Click
    lblDropdownstaff.Text = "Elaine"
    selectedStaffMember = "Elaine"

    generatePage(selectedStaffMember)
End Sub

Protected Sub lstStaffSelect3_Click(ByVal sender As Object, e As EventArgs) Handles lstStaffSelect3.Click
    lblDropdownstaff.Text = "Dawn"
    selectedStaffMember = "Dawn"

    generatePage(selectedStaffMember)
End Sub

Function findIndex(ByVal selectedStaffMember As String)
    Select Case selectedStaffMember
        Case "Salon"
            staffdropdownindex = 0
        Case "Elaine"
            staffdropdownindex = 1
        Case "Dawn"
            staffdropdownindex = 2
        Case Else
            staffdropdownindex = 3
    End Select
    staffindex = staffdropdownindex
    Return staffindex
End Function

Protected Sub generatePage(ByVal selectedStaffMember As String)
    staffindex = findIndex(selectedStaffMember)

    Dim sqlCommandString As String
    If staffindex <> 0 Then

        sqlCommandString = "SELECT [Appointments].[DateTimeStart], [Appointments].[DateTimeEnd], [Appointments].[AppointmentID], [CustomerData].[Forename], [CustomerData].[Surname] " &
                           "FROM [Appointments] " &
                           "INNER JOIN [CustomerData] " &
                           "ON [CustomerData].[CustomerID] = [Appointments].[CustomerID] " &
                           "WHERE [Appointments].[HairdresserID] = " & staffindex &
                           "ORDER BY [Appointments].[DateTimeStart] ASC"

    ElseIf staffindex = 0 Then
        sqlCommandString = "SELECT [Appointments].[DateTimeStart], [Appointments].[DateTimeEnd], [Appointments].[AppointmentID], [CustomerData].[Forename], [CustomerData].[Surname] " &
                           "FROM [Appointments] " &
                           "INNER JOIN [CustomerData] " &
                           "ON [CustomerData].[CustomerID] = [Appointments].[CustomerID] " &
                           "ORDER BY [Appointments].[DateTimeStart] ASC"

    End If

    ds_estrella.Clear()
    GridViewConnection(sqlCommandString)
End Sub

Protected Sub GridViewConnection(ByVal sqlCommandString As String)
    Staffgv.DataSource = Nothing
    Staffgv.DataBind()

    Dim dbConn As New SqlConnection(connString)

    Try
        dbConn.Open()

        da_estrella = New SqlDataAdapter(sqlCommandString, dbConn)
        da_estrella.Fill(ds_estrella, "StaffView")

        Dim icount As Integer = ds_estrella.Tables(0).Rows.Count
        Staffgv.DataSource = ds_estrella

        If ds_estrella.Tables(0).Rows.Count > 0 Then
            Staffgv.DataSource = ds_estrella
            Staffgv.DataBind()
        Else
            Staffgv.DataSource = ds_estrella
            Staffgv.DataBind()
            Dim columncount As Integer = Staffgv.Rows(0).Cells.Count

            'No data found in this case
        End If

        dbConn.Close()
    Catch ex As Exception
        lblDropdownstaff.Text = "FAILED"
    End Try
End Sub

Protected Sub Staffgv_PageIndexChanging(ByVal sender As Object, e As GridViewPageEventArgs) Handles Staffgv.PageIndexChanging
    Staffgv.PageIndex = e.NewPageIndex
End Sub

Protected Sub Staffgv_RowCommand(ByVal sender As Object, e As GridViewCommandEventArgs)
    If (e.CommandName = "FillStaffTables") Then
        txtAppointmentID.Text = e.CommandArgument
    End If
End Sub  
Community
  • 1
  • 1
Michael Dono
  • 61
  • 1
  • 8
  • Just out of curiosity... are you using ``'s? – zgood Feb 19 '16 at 20:35
  • No, I don't know what that is, is it something I should be using? – Michael Dono Feb 19 '16 at 20:37
  • No its not something you need, but it can create problems, kind of like what you have described, so I was just checking – zgood Feb 19 '16 at 20:43
  • so the filtered row data is correct, but the AppointmentIDs are not? – terbubbs Feb 19 '16 at 21:28
  • yeah, when the `GridView` is first displayed to the user the buttons in the GridView output the correct value (even when the filter is set to only show certain values). The correct values are shown only when the GridView is first loaded, afterwards the value the buttons give doesn't change from the original values. – Michael Dono Feb 19 '16 at 21:43

1 Answers1

0

It took a bit of work, but I used your code and built a running web application so I can help debug this. The first thing you might want to do is add the following line as the first line inside your Page_Load

If Me.IsPostBack Then Exit Sub

This will make it so that your entire Page_Load block only runs once and so that the gridview doesn't keep returning to its original state.

For example, try clicking the "Elaine" button and then click the "____" button inside the gridview. This would perviously lead to the entire gridview returning to its original state, but now it should keep the filtered gridview present.

You may move the aforementioned Me.IsPostBack line up/down within your Page_Load, just know that any code below it will only run once: When the page first loads.


The second thing you should do is add another line in Page_Load

txtAppointmentID.Text = String.Empty

It should be placed above the Me.IsPostBack line. This will clear out the textbox when the page reloads so that said textbox doesn't hold a previous/stale value in it when another button is clicked.


Lastly, at the very top of your vb file, it's good practice to add the following lines (if you haven't already)

Option Strict On
Option Explicit On

These options will bring out a few more errors which are often very easy to fix yet, if left as they are, they can sometimes cause very subtle bugs/problems that are quite difficult to track down. These options will generally help one to write better code.

Mr.Z
  • 542
  • 2
  • 5
  • 18
  • 1
    Thank you so much! It works using the first two bits you said, tried turning Strict and Explicit on (was never told it was something I should be doing) but I was getting a few errors which I'm not quite sure how to fix. The error is "Option Strict On disallows implicit conversions from 'Object' to 'Integer'." Should I be setting the function as an object, and how should I handle calling the function? – Michael Dono Feb 20 '16 at 18:27
  • Also just wanted to thank you again, I really do appreciate the help! – Michael Dono Feb 20 '16 at 18:28
  • 1
    You're most welcome. The error should be solved by modifying your `findIndex` function to indicate that it returns an `Integer` like this: `Function findIndex(ByVal selectedStaffMember As String) As Integer`. – Mr.Z Feb 20 '16 at 18:36
  • Thanks, in `txtAppointmentID.Text = e.CommandArgument` I'm getting another conversion error, I'm not sure how to deal with this one? – Michael Dono Feb 20 '16 at 19:39
  • 1
    For this error, and for other similar ones, you need to make the correct type conversion. In this case you'd want to do `CStr(e.CommandArgument)` to convert from an `Object` to a `String`. [MSDN has a complete list of the conversion functions](https://msdn.microsoft.com/en-us/library/kca3w8x6.aspx#Anchor_0). _(PS: you can up-vote comments too, if you think they were helpful to you. This is the StackOverflow equivalent of a Thank You)_. – Mr.Z Feb 20 '16 at 20:48