Dynamic DataGridView filtering in C#

Posted in .NET 2.0 | .NET UI Controls | DataGridView at Wednesday, December 3, 2008 9:31 PM GMT Standard Time

In a few lines of code, we can convert a DataGridView control in a powerfull fully searchable control with dynamically generated filters for each column of field the DataGridView is binded to.

How does it work?

  1. The DataGridControl is binded to the datasource.
  2. The user hits the button (or shortcut) to start the dynamic filtering feature.
    1. A new form is dinamycally generated on top of the DatagridView control (it has some transparency on it so you can still see the DataGridView data on the background)
    2. The form contains several textboxes, one per each column or field the DataGridView datasource contains (you can change that behaviour)
    3. When the user starts entering text in any of the textboxes, the filter condition is applied to the underlying datasource (for every keystroke) so you can see how the filtered data looks on the DataGridView as you are typing.
    4. You can, of course define filters for one or more textboxes (fields) at the time, so you can work with multiple filters for many columns/fields.
  3. You can choose whatever you create a dynamically generated search form that contains all the fields on DataGridView datasource, or the ones of your choice (video and example code shows both cases).

Screenshots


This screenshot shows the dynamically search form generated with all the fields of the underlying DataGridView

This screenshot shows the dynamically search form generated with some of the fields of the underlying DataGridView

Demo Video


(sorry about the video quality. if you are interested, please download the demo. it may be worthy)

Some code:

 /// 
        /// Build texbox controls for dinamyc search form based on fields collection
        /// 
        /// 
        private void BuildControls(List fields) {
            int top = 10;
            bool focused = false;

            #region Loop for each field
            foreach (field f in fields)
            {
                Label label = new Label();
                label.Text = f.FriendlyName + ":";
                label.Top = top;
                label.Left = 5;
                label.AutoSize = true;
                this.Controls.Add(label);

                TextBox textbox = new TextBox();
                textbox.TextChanged += new EventHandler(textBox_TextChanged);
                textbox.Tag = f.Field;
                textbox.Top = top;
                textbox.Left = 68;
                textbox.Width = this.Width - 80;
                if (!focused) {

                    textbox.Focus(); //the first control focused
                    focused = true;
                }
                top += 35;
                this.Controls.Add(textbox);
            }
            #endregion

            this.Height = top + 30;
        }


  // Raise event to parent form if textbox content changes
        private void textBox_TextChanged(object sender, EventArgs e)
        {
            if (TextChanged != null)
                TextChanged(GetFilterValues());
        }


        #region Shortcuts
        private void frmSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == Keys.Escape) || (e.KeyCode == Keys.Enter))
                Close();
        }
        #endregion


namespace dynamicGridFilter
{
    /// 
    /// This struct contains information about each field to be filtered along with filter value, if exists.
    /// 
    public struct field {
        public string Field;
        public string FriendlyName;
        public string Value;
    }
}


namespace dynamicGridFilter
{
    public delegate void SearchContextChangedHandler(List fields);
}

Complete source code available to download:

Includes full source code and compiled binary (use it at your own risk)
dynamicGridFilter.zip (50,23 KB)

What's next?!

If could have gone all the way up to creating a custom control that inherits from DataGridView and has all the logic embedded. Well, you have here all you need for doing it yourself, so don't call me lazy! :P

Comments are welcome!


AddThis Social Bookmark Button

Friday, December 12, 2008 2:42:13 PM (GMT Standard Time, UTC+00:00)
Hi

Thank you - Highly appreciated.

/morte
Morten
Friday, January 9, 2009 5:05:04 AM (GMT Standard Time, UTC+00:00)
wow!! good. nice!

thank you.
..you source testing ..
Sunday, January 11, 2009 11:11:53 AM (GMT Standard Time, UTC+00:00)
It's what i m looking for. Thanks a lot
Sumon
Friday, February 20, 2009 3:30:12 PM (GMT Standard Time, UTC+00:00)
Hello to all, congratulations for the post, I find it very interesting. I wanted to know whether you can use the code for a university project and whether those who should I ask.

Thank you.
Friday, February 20, 2009 4:36:45 PM (GMT Standard Time, UTC+00:00)
Hi Pascal,

Thanks for your comments.
You can use the code for any project for any purpose.

Best regards,

ivan
Monday, April 6, 2009 10:49:56 PM (GMT Daylight Time, UTC+01:00)
Hi
i downloaded your program.
that is really nice and good!
please help me if possible for you..
i want change your program and use in my project
i created a database project for my universitys project by oracle and then interface by c# but that is just an interface.
if possible for you say me where i should change in your program that it show my data?
my data: "dataset1"
table: "d_driver"
please ...please ...please... Help me have a Dynamic DataGridView filtering in my project!
thanks. max from Ukraine.

MAX
Thursday, September 3, 2009 10:59:39 AM (GMT Daylight Time, UTC+01:00)
really like the dynamic search field and would like to use it in my project. however do you have a simple way of getting the id of the selected field? for now i have a visitorid as the first column and would like to extend the grid so that users can be edited etc. i am using an invisible label to get the id for now, not a good way for sure :)

thanks,
Mikael
Mikael
Monday, October 26, 2009 9:53:46 AM (GMT Standard Time, UTC+00:00)
Mikael:

if i understand correctly, you want your application to get the ID of that row (being selected) right?
if so, you can try this: create a cellclick event and use RowIndex and the cell number to get the visitorID.

sample code:

//Assuming your cell zero will be the ID you wanted (primary key for your table)
private void dataGridVisitors_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
string visitorId = dataGridVisitors.Rows[e.RowIndex].Cells[0].Value.toString();
}


hope this helps!
Andy
Tuesday, October 27, 2009 8:55:12 AM (GMT Standard Time, UTC+00:00)
Thank you very much. This is great helpful.
Monday, July 5, 2010 12:21:48 PM (GMT Daylight Time, UTC+01:00)
Hey man , you are my hero....
really really appreciate you because of your useful code...
be success
yours truly
Ramin
Ramin
Comments are closed.