سؤال

I have a readymade library(dll) given to me, which has important data, i m able to take that data into Datatable and successfully displaying it on a GridView.

Now my further task is the Data what it is displaying in GridView should be filterable, meaning if i click on any column on a row it should filtered results of similar columns.

This is my GridView Result

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name1              Info1            ID1              Time1
Name2              Info2            ID2              Time2
Name1              Info3            ID3              Time3
Name3              Info2            ID4              Time4
Name4              Info4            ID3              Time5
Name5              Info5            ID5              Time5

Now what i want is if i click on Name1 it should show

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name1              Info1            ID1              Time1
Name1              Info3            ID3              Time3

And if i click on Info2 it should show

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name2              Info2            ID2              Time2
Name3              Info2            ID4              Time4

I think my question is clear now. How can i achieve this? Thanks in advance

هل كانت مفيدة؟

المحلول

So you want to filter a GridView's DataSource by a value of a cell the user clicked on. These are multiple tasks in one, i'll try to explain all.

The major task is to enable that every cell in the GridView reacts on a user's click, handling that click-event on serverside and get somehow the value from that cell.

I've used a DataTable in following example, replace it with your type of datasource. If you need to add custom events/controls to GridViewRows the best place is RowCreated since this is called on every postback not only on databinding. Note that you don't have the DataItem at this stage.

protected void gridView1_RowCreated(Object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        for(int i = 0; i < e.Row.Cells.Count; i++)
        {
            TableCell cell = e.Row.Cells[i];
            cell.ToolTip = "Click to filter by this value";
            string js = string.Format("var txt=document.getElementById('{0}');txt.value='{1} {2}';{3}"
                , TxtFilter.ClientID, e.Row.RowIndex, i
                , ClientScript.GetPostBackClientHyperlink(TxtFilter, null));
            cell.Attributes["onclick"] = js;
        }
    }
}

As you can see i've added the clientside onclick event to each cell. I'm using a hidden TextBox(display:none) with AutoPostBack=true to store the row and cell the user has clicked. Now you're able to handle and process the click event on serverside.

protected void FilterGrid(object sender, EventArgs e)
{
    TextBox txtFilter = (TextBox)sender;
    string[] parts = txtFilter.Text.Split();
    int row = int.Parse(parts[0]);
    int col = int.Parse(parts[1]);
    gridView1.DataSource = GetData(row, col);
    gridView1.DataBind();
}

// replace with your DAL, used a DataTable for testing
private DataTable GetData(int rowIndex = -1, int colIndex = -1)
{
    DataTable tblData = getDataSource(); 
    if (rowIndex > -1 && colIndex > -1)
    {
        var field = tblData.Columns[colIndex];
        var row = tblData.Rows[rowIndex];
        var value = row[field];
        // now use Linq-To-DataSet to filter the table, remember to add 'using System.Linq'
        tblData = tblData.AsEnumerable()
            .Where(r => !r.IsNull(field) && r[field].Equals(value))
            .CopyToDataTable();
    }

    return tblData;
}

Here's the aspx of my sample page:

<asp:TextBox ID="TxtFilter" runat="server" style="display:none" AutoPostBack="true" OnTextChanged="FilterGrid" />
<asp:GridView ID="gridView1" runat="server" AutoGenerateColumns="False" OnRowCreated="gridView1_RowCreated"  >
   <Columns>
       <asp:TemplateField HeaderText="HeaderCol1">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol1" runat="server" Text='<%#Eval("HeaderCol1") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol2">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol2" runat="server" Text='<%#Eval("HeaderCol2") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol3">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol3" runat="server" Text='<%#Eval("HeaderCol3") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol4">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol4" runat="server" Text='<%#Eval("HeaderCol4") %>' />
            </ItemTemplate>
       </asp:TemplateField>
  </Columns>
</asp:GridView>

نصائح أخرى

1) Create new pages (.aspx files) that display the details of the person etc.

2) In your current GridView you have to use HyperLinkField instead of simple BoundField:

      <asp:hyperlinkfield datatextfield="UnitPrice"
        datatextformatstring="{0:c}"
        datanavigateurlfields="ProductID"
        datanavigateurlformatstring="~\yourNewPage.aspx?ProductID={0}"          
        headertext="HeaderCol1"
        target="_blank" />

This will now render a hyperlink that, when clicked, will open the details in a new page.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top