locked
Filter Search results in DataGrid RRS feed

  • Question

  • Hi 

    I want to have a search text box that will search every cell DataGrid and only display results.  For example say the DataGrid has this in it:

    FirstName		LastName
    Bob                     Smith
    Mike                    Williams
    Sam                     Johnson

    In the search text box if the user types in "o" the following would appear;

    FirstName		LastName
    Bob                     Smith
    Sam                     Johnson

    Then the user types "oh" then

    FirstName		LastName
    Sam                     Johnson

    Thanks

    Thursday, October 10, 2013 5:02 PM

Answers

  • Hi,

    For your requirement, we can use LINQ to search specific items in ObservableCollection:

    ObservableCollection<Employee> oc = new ObservableCollection<Employee>();
    
    public MainWindow()
    {
                InitializeComponent();
                
                oc.Add(new Employee() { FirstName = "Bob", LastName = "Smith" });
                oc.Add(new Employee() { FirstName = "Mike", LastName = "Williams" });
                oc.Add(new Employee() { FirstName = "Sam", LastName = "Johnson" });
                
                dg.ItemsSource = oc;
    }
    
    private void btnFilter_Click(object sender, RoutedEventArgs e)
    {
                dg.ItemsSource = oc.Where(X => X.FirstName.IndexOf(filter.Text) > -1 || X.LastName.IndexOf(filter.Text) > -1);
    }

    Employee Class:

    public class Employee
    {
            public string firstName;
            public string lastName;
    
            public string FirstName
            {
                get { return firstName; }
                set { firstName = value; }
            }
    
            public string LastName
            {
                get { return lastName; }
                set { lastName = value; }
            }
    }

    Screenshot:

    Sample download link:
    http://sdrv.ms/1bhxwWK

    Please check the following references:

    #LINQ (Language-Integrated Query)
    http://msdn.microsoft.com/en-us/library/vstudio/bb397926.aspx

    #String.IndexOf Method (String)
    http://msdn.microsoft.com/en-us/library/k8b1470s.aspx


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Proposed as answer by IssueKiller Friday, October 11, 2013 1:20 PM
    • Unproposed as answer by Xaphann Friday, October 11, 2013 2:27 PM
    • Marked as answer by Xaphann Friday, October 11, 2013 7:31 PM
    Friday, October 11, 2013 5:41 AM
  • Ok, figured out a way, not sure if is the best please any feedback would be great.  This is what I did;

    using (SqlConnection con = new SqlConnection(ConString))
                {
                    CmdString = "select firstName, lastName from myTable";
                    SqlCommand cmd = new SqlCommand(CmdString, con);
                    SqlDataAdapter sda = new SqlDataAdapter(cmd);
                    DataTable dt = new DataTable("myTable");
                    sda.Fill(dt);
                     oc = new ObservableCollection<searchCollection>();
    
                    foreach (DataRow dr in dt.Rows)
                    {
                        string fName = dr.ItemArray[0].ToString();
                        string lName = dr.ItemArray[1].ToString();
                        oc.Add(new Employee() { FirstName = fName, LastName = lName });
    
                    }
                    myDataGrid.ItemsSource = oc;
                }

    • Marked as answer by Xaphann Friday, October 11, 2013 7:30 PM
    Friday, October 11, 2013 7:30 PM

All replies

  • Hi,

    For your requirement, we can use LINQ to search specific items in ObservableCollection:

    ObservableCollection<Employee> oc = new ObservableCollection<Employee>();
    
    public MainWindow()
    {
                InitializeComponent();
                
                oc.Add(new Employee() { FirstName = "Bob", LastName = "Smith" });
                oc.Add(new Employee() { FirstName = "Mike", LastName = "Williams" });
                oc.Add(new Employee() { FirstName = "Sam", LastName = "Johnson" });
                
                dg.ItemsSource = oc;
    }
    
    private void btnFilter_Click(object sender, RoutedEventArgs e)
    {
                dg.ItemsSource = oc.Where(X => X.FirstName.IndexOf(filter.Text) > -1 || X.LastName.IndexOf(filter.Text) > -1);
    }

    Employee Class:

    public class Employee
    {
            public string firstName;
            public string lastName;
    
            public string FirstName
            {
                get { return firstName; }
                set { firstName = value; }
            }
    
            public string LastName
            {
                get { return lastName; }
                set { lastName = value; }
            }
    }

    Screenshot:

    Sample download link:
    http://sdrv.ms/1bhxwWK

    Please check the following references:

    #LINQ (Language-Integrated Query)
    http://msdn.microsoft.com/en-us/library/vstudio/bb397926.aspx

    #String.IndexOf Method (String)
    http://msdn.microsoft.com/en-us/library/k8b1470s.aspx


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Proposed as answer by IssueKiller Friday, October 11, 2013 1:20 PM
    • Unproposed as answer by Xaphann Friday, October 11, 2013 2:27 PM
    • Marked as answer by Xaphann Friday, October 11, 2013 7:31 PM
    Friday, October 11, 2013 5:41 AM
  • you can also do it using a listcollectionview and when your text changes then change the filter i.e.

    ListCollectionView lv = new ListCollectionView(yourcollection);
    dg.ItemsSource = lv;
    
    yourtextbox_textchangedevent(object sender, RoutedEventArgs e)
    {
    if(String.IsNullOrEmpty(yourtextbox.Text))
    lv.Filter = null;
    else
    lv.Filter = new Predicate<object>(o => ((Employee)o).FirstName.Contains(yourtextbox.Text)||((Employee)o).LastName.Contains(yourtextbox.Text));
    }

    code can be tidied up but just written without testing to give you the general idea.  using above it will filter the datagrid as you type rather than having to click a filter button.

    cheers

    andy

    • Proposed as answer by IssueKiller Friday, October 11, 2013 1:20 PM
    Friday, October 11, 2013 8:55 AM
  • That looks really good Franklin. Just a quick question, the datagrid already has an itemssource based on an ADO connection;

    using (SqlConnection con = new SqlConnection(ConString))
                {
                    CmdString = "select firstName, lastName from myTable";
                    SqlCommand cmd = new SqlCommand(CmdString, con);
                    SqlDataAdapter sda = new SqlDataAdapter(cmd);
                    DataTable dt = new DataTable("myTable");
                    sda.Fill(dt);
                    myDataGrid.ItemsSource = dt.DefaultView;
                }

    What is the best way to link ItemSource to collection?


    • Edited by Xaphann Friday, October 11, 2013 3:23 PM minor edit
    Friday, October 11, 2013 2:53 PM
  • Ok, figured out a way, not sure if is the best please any feedback would be great.  This is what I did;

    using (SqlConnection con = new SqlConnection(ConString))
                {
                    CmdString = "select firstName, lastName from myTable";
                    SqlCommand cmd = new SqlCommand(CmdString, con);
                    SqlDataAdapter sda = new SqlDataAdapter(cmd);
                    DataTable dt = new DataTable("myTable");
                    sda.Fill(dt);
                     oc = new ObservableCollection<searchCollection>();
    
                    foreach (DataRow dr in dt.Rows)
                    {
                        string fName = dr.ItemArray[0].ToString();
                        string lName = dr.ItemArray[1].ToString();
                        oc.Add(new Employee() { FirstName = fName, LastName = lName });
    
                    }
                    myDataGrid.ItemsSource = oc;
                }

    • Marked as answer by Xaphann Friday, October 11, 2013 7:30 PM
    Friday, October 11, 2013 7:30 PM