0

I want my DataGridView filters data as I type.

enter image description here

    private void textSearch_TextChanged(object sender, EventArgs e)
    {
        Console.WriteLine("text_search_TextChanged()");

        LoadToDataGridView();            

        filterTextBox.Focus();
    } 

This code is painfully slow. It halts at each character as I type.

What can I do to improve the speed?

.

Source code

    void LoadToDataGridView()
    {
        Console.WriteLine("LoadToDataGridView()...");

        dataGridView1.Rows.Clear();

        IList<Word> items = null;

        string like = filterTextBox.Text;

        if (groupCheckBox.Checked || learntCheckBox.Checked)
        {
            LearntTypeEnum learntType = (LearntTypeEnum)learntComboBox.SelectedIndex;
            int groupNo = (int)groupComboBox.Items[groupComboBox.SelectedIndex];
            int correctness = InMemoryValues.CorrectnessRepetition;

            if(groupCheckBox.Checked && learntCheckBox.Checked)
            {
                if (learntType == LearntTypeEnum.All)//all
                {
                    items = _wordDatabase.GetByGroup(groupNo);//, like);
                }
                else if (learntType == LearntTypeEnum.NotLearnt)//not learnt
                {
                    items = _wordDatabase.GetByCorrectnessBelow(groupNo, correctness);//, like);
                }
                else//learnt
                {
                    items = _wordDatabase.GetByCorrectnessBeyond(groupNo, correctness);//, like);
                }
            }
            else if (groupCheckBox.Checked)
            {
                items = _wordDatabase.GetByGroup(groupNo);//, like);
            }
            else // if(learntCheckBox.Checked)
            {
                if (learntType == LearntTypeEnum.All)//all
                {
                    items = _wordDatabase.Get();//ByLike(like);
                }
                else if (learntType == LearntTypeEnum.NotLearnt)//not learnt
                {
                    items = _wordDatabase.GetByCorrectnessBelow(correctness);//, like);
                }
                else//learnt
                {
                    items = _wordDatabase.GetByCorrectnessBeyond(correctness);//, like);
                }
            }
        }
        else
        {
            items = _wordDatabase.Get();
        }

        if (items != null)
        {
            if (items.Count > 0)
            {
                Console.WriteLine(items[0].Name);

                int i = 0;
                foreach (Word c in items)
                {
                    dataGridView1.Rows.Add((c.CorrectnessCount==InMemoryValues.CorrectnessRepetition)?true:false
                        ,c.GroupNo, c.Name, c.CorrectnessCount, c.Meaning);
                    dataGridView1.Rows[i].Tag = c;
                    ++i;
                }

                IList<Word> likes = _wordDatabase.GetByLike(like);

                if(likes != null)
                {
                    if(likes.Count > 0)
                    {
                        Word word = likes[0];

                        SetFocusToWord(word);
                    }
                }

                totalRowsLabel.Text = items.Count.ToString();
            }
            else
            {
                totalRowsLabel.Text = "0";
            }
        }
        else
        {
            totalRowsLabel.Text = "0";
        }
    } 
user366312
  • 16,949
  • 65
  • 235
  • 452
  • @john, this is a desktop application. – user366312 Oct 26 '17 at 04:57
  • on form load capture all data in list and on keypress event filter data from that list instead of hitting the database and if any change made in data also update data in list – Hitesh Thakor Oct 26 '17 at 04:57
  • @HiteshThakor, hmm...good idea. But, in that case, I have to massively recode. – user366312 Oct 26 '17 at 04:59
  • @anonymous At least you got the principle: adding delay on `KeyPress` event before querying database for displaying autocomplete results is recommended. I think this question more suitable for performance review in [codereview.se]. – Tetsuya Yamamoto Oct 26 '17 at 04:59
  • @anonymous i don't think so you need to change more – Hitesh Thakor Oct 26 '17 at 05:00
  • 1
    Have you ever heard anything about data binding? You can load data using a `SqlDataAdapter` and then set the result `DataTable` as `DataSource` of the `DataGridView`. Then to filter data, it's enough to use `DataView.RowFilter` of the `DataTable`. There are a lot of example in this topic. For example take a look at [this one](https://stackoverflow.com/a/33495229/3110834) or if you are going to use Entity Framework, take a look at [this one](https://stackoverflow.com/a/35978408/3110834). – Reza Aghaei Oct 26 '17 at 05:24
  • @anonymous I deleted my comment because you failed to understand the point I was making. Just because my concept was typically used on the web, doesn't mean that it can't be applied just as easily or effectively do a desktop application. – ProgrammingLlama Oct 26 '17 at 05:43
  • Do not make the user wait for the data to return from the database on each key press. Instead, create a search button and have your users press it to get the data from the database. If you want to, you can filter data already present in your grid by key press, that process is very fast and users will not have to wait. – Zohar Peled Oct 26 '17 at 05:54
  • @RezaAghaei, okay. If I use data binding, how can I use New, Edit, Delete buttons? I was writing the code like the following: https://i.imgur.com/PcZ9lxI.png – user366312 Oct 26 '17 at 08:11
  • There are a lot of examples around. For example, take a look at [this post](https://stackoverflow.com/q/38165043/3110834) or [this one](https://stackoverflow.com/q/37805229/3110834) or [this one](https://stackoverflow.com/q/36274296/3110834) and read my answers. They will save lot's of your time! – Reza Aghaei Oct 26 '17 at 08:55

0 Answers0