VB Gridview selects wrong row for editing

2020-04-27 01:25发布

问题:

Hello I have a searchbox and when I search for a record it is fine the records shows up however once I click edit on the gridview the page does a postback and all the records show back up with the first record selected for editing. How can I disable this post back or make it when I click edit all the records do not display again?

VB.CodeBehind

Protected Sub btnClear_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClear.Click
    txtSearch.text = ""
    sourcegridview.DataBind()

End Sub

Protected Sub btnSearch_Click(sender As Object, e As System.EventArgs) Handles btnSearch.Click
    SqlDataSource1.SelectCommand = "select * from Stg_Employee_All_Info where Name like '%" & txtSearch.Text & "%'"
    SqlDataSource1.DataBind()
End Sub

Gridview Code

<asp:GridView ID="sourcegridview" runat="server" AllowPaging="True" 
        AutoGenerateColumns="False" BackColor="White" BorderColor="#3366CC" 
        BorderStyle="None" BorderWidth="1px" CellPadding="4" 
        DataSourceID="SqlDataSource1" Width="422px" AllowSorting="True" 
        DataKeyNames="Row">
        <Columns>
            <asp:BoundField DataField="Row" HeaderText="Row"  
                SortExpression="Row" ReadOnly="True" />
            <asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True" 
                SortExpression="Name" />
            <asp:BoundField DataField="Dept" HeaderText="Dept" ReadOnly="True" 
                SortExpression="Dept" />
            <asp:TemplateField HeaderText="Hide_Bday">
                <EditItemTemplate>
                    <asp:CheckBox ID="chkBday" runat="server" Checked='<%# Bind("Hide_Bday") %>' />
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="lblHideBday" runat="server" Text='<%# Eval("Hide_Bday") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Hide_Anniv">
                <EditItemTemplate>
                    <asp:CheckBox ID="chkAnniv" runat="server" 
                        Checked='<%# Bind("Hide_Anniv") %>' />
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="lblHideAnniv" runat="server" Text='<%# Eval("Hide_Anniv") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:CommandField ShowEditButton="True" />
        </Columns>
        <EmptyDataTemplate>
            <asp:CheckBox ID="chkboxHideBday" runat="server" 
                Checked='<%# Eval("Hide_Bday") %>' Visible='<%# Eval("Hide_Bday") %>' />
        </EmptyDataTemplate>

I populate and update the gridview with a sqldatasource which references a stored procedure

Gridview populate code

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:a_Kronos %>" 
    SelectCommand="SELECT [Row], [Name], [Dept], [Hide_Bday], [Hide_Anniv] FROM [Stg_Employee_All_Info]" 
    UpdateCommand="usp_insertoptout" UpdateCommandType="StoredProcedure">
    <UpdateParameters>
        <asp:Parameter Name="Hide_Bday" Type="Int32" />
        <asp:Parameter Name="Hide_Anniv" Type="Int32" />
    </UpdateParameters>
</asp:SqlDataSource>

回答1:

The problem is when you click on search it sets the SelectCommand, but only for that single round-trip to the server. The SelectCommand is not persisted anywhere so when you are clicking "Edit", the grid goes right back to using SqlDataSource1's initial command.

Early versions of the ASP.NET GridView stored the SelectCommand text in ViewState, but that was removed for security reasons. As they put it:

For security purposes, the SqlDataSource control no longer stores commands in ViewState by default. Since it is technically possible to decode the contents of ViewState on the client, storing sensitive information about the database backend in this field could expose you to an information disclosure threat.

So instead, you will need to bind the Grid manually and find your way of persisting the SelectCommand across multiple post-backs. Here is an example using Session:

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    SqlDataSource1.SelectCommand = If(Session("SearchSelectCommand"), "SELECT [Row], [Name], [Dept], [Hide_Bday] ...")
    SqlDataSource1.DataBind()
End Sub

Protected Sub btnSearch_Click(sender As Object, e As System.EventArgs) Handles btnSearch.Click
    Dim searchQuery As String = "select * from Stg_Employee_All_Info where ..."
    Session("SearchSelectCommand") = searchQuery
    SqlDataSource1.SelectCommand = searchQuery
    SqlDataSource1.DataBind()
End Sub