I have a gridview loaded from a database with a checkbox in the first column. What I want is that when clicking on any row the grid will be filtered to show only the rows in which the value of the second cell is the same as the one I clicked on (having the option to select more rows with that value). Removing the checks he would reload all the information again. I tried doing it using the OnChecked event, but due to AutoPostBack it filters but loses the value of the checkbox checked. What is the best way to do what I want? I hope I have been explicit. Thank you

asp:GridView ID="gridview"   runat="server" AutoGenerateColumns="false"  DataKeyNames="Id">
<Columns>
    <asp:TemplateField>
        <ItemTemplate>
            <asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:BoundField DataField="Document"  ItemStyle-Width="10%" HeaderText="Documento" />
    <asp:BoundField DataField="Entidad"  ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>

For Each row As GridViewRow In gvEncomendasPendentes.Rows
        If row.RowType = DataControlRowType.DataRow Then
            Dim chkRow As CheckBox = TryCast(row.Cells(0).FindControl("chkRow"), CheckBox)


            If chkRow.Checked Then

                'Bind with filter

            End If

End If

Next

1 Answers

0
Stephen Wrighton On

Does the table display the entire dataset at all times? If so, I'd check into client-side filtering (JavaScript). Not having the round trip to the server/database would make your page a lot more responsive.

But assuming that's not the case, and to actually answer the posted question, here's how I'd approach it in the VB.Net Code. Try changing the Change Event like this:

Protected Sub chkRow_CheckedChanged (sender as object, e As EventArgs)
   Dim chk As CheckBox = DirectCast(sender, CheckBox)
   dim grv As GridRowView = DirectCast(chk.NamingContainer, GridRowView)
   dim hdn AS HiddenField = grv.FindControl("hdnFieldWithValue")
   If chk.Checked then 
     AddValueToFilerList(hdn.Value)
   Else 
     RemoveValueFromFilterList(hdn.Value)
   End If 

  BindGridView()
End Sub

Your way does work, but that has a Log(N) time on processing, as it needs to look at every row in the grid. The above way will KNOW which checkbox was checked, and deal with it appropriately.

And this small change to the markup:

<asp:hiddenField runat='server' id='hdnFilterList' />
<asp:GridView ID="gridview" runat="server" AutoGenerateColumns="false"  DataKeyNames="Id">
<Columns>
    <asp:TemplateField>
        <ItemTemplate>
            <asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" checked='<%# CheckValueInFilterList(Eval("Entidad")) %>' />
            <asp:hiddenField id="hdnFieldWithValue" runat="server" value='<%# Eval("Entidad")' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:BoundField DataField="Document"  ItemStyle-Width="10%" HeaderText="Documento" />
    <asp:BoundField DataField="Entidad"  ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>

You'll also a function something like this:

Protected Function CheckValueInFilterList(input as string) as boolean 
     Return MyListOfFilterItems.Contains(input)
End Function

The purpose of that would be to see if the input is contained in your list of filters you're applying to your query and returning true/false depending on that.

Which is directly related to why you're not retaining a check in the checkboxes between postbacks. Since you're rebinding the grid, the existing form state is thrown away in favor of the values from the bind. Since your markup lacked a setter for the checkbox's checked state in the databind, it always resorted to false.

I also added a hidden field to the Markup which would contain the filter list as some type of serialized string (JSON, XML, etc). I'd read it from that field on the Page Load where IsPostBack is True, and always write the list to it in the PreRender event. The point is to just have that passed back and forth through the posted form state so that you can remember them between postbacks.

Maintaining that list of filters in a control outside of the gridview as described does add a bit of overhead in the data that is sent to/from the server on roundtrips. But I wouldn't expect that to a large amount, and would expect a preformance increase due to not having to iterate through the entire gridview item list on every postback.