Resolved Combobox Filter

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
A novice question if I may.

I'm trying to cascade filter comboboxes to DGV in my winforms project.

I have a list derived from a class that populates cbx1 with CategoryA items, I'm trying to populate cbx2 with CategoryB items in the SelectedIndexChanged event based on the choice in cbx1 and displaying only the relevant categories in cbx2. It works as expected but without the filter.
The commented out LINQ is an attempt to do this but returns errors.

A point in the right direction would be great, thanks.

C#:
void cbxCategoryAFill()
        {
            List<Screwfix> scr = sc.GetAllScrewfixResults();

            this.comboBox1.DataSource = scr.Select(t => t.CategoryA).Distinct().ToList();
            comboBox1.Text = "--Select--";
        }
        void cbxCategoryBFill()
        {
            List<Screwfix> scr = sc.GetAllScrewfixResults();
            
            this.comboBox2.DataSource = scr.Select(t => t.CategoryB).Distinct().ToList();
            comboBox2.Text = "--Select--";
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.BeginInvoke((MethodInvoker)delegate { comboBox1.Text = "-Select-"; });//Note Resets combobox after selection

            List<Screwfix> scr = sc.GetAllScrewfixResults();
            dgvLeft.DataSource = scr.Where(x => x.CategoryA.Contains(comboBox1.Text)).ToList();

            // comboBox2.DataSource = ((IEnumerable<string>)dgvLeft.DataSource)
            //.Where(x =>
            //{
            //    return x == (string)comboBox1.SelectedValue;
            //});
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.BeginInvoke((MethodInvoker)delegate { comboBox1.Text = "-Select-"; });

            List<Screwfix> scr = sc.GetAllScrewfixResults();

            dgvLeft.DataSource = scr.Where(x => x.CategoryB.Contains(comboBox2.Text)).ToList();
        }
 

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
Why? Are your users so simple that they don't understand how a basic GUI works? Do you also default a TextBox to "Type"? If you think the users can work out how to do one, why do you think they can't work out how to do the other?
God I love straight talk! :).
It's a personal app for work so there's just me using it so far, but who knows, If I keep practicing hard and getting good advice like this. (y)
 

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
What do you mean "system info"? Was it something like "Business.ClassLibrary.ScrewfixCat2"? If so, it sounds like your DisplayMember seeing doesn't work either. I suspect that your cbxCategoryBFill() was not called. Set a breakpoint on that method to make sure that it is being called.
Hello again, thanks for your patience.
yes, that's the exactly what's filling the combo. I set a breakpoint as you suggested and the exception was thrown straight away.
One thing I'm noticing is, when using the original filter code, I get the parent table Id(CatId) numbers in cbxCat2
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
6,068
Location
Chesapeake, VA
Programming Experience
10+
I set a breakpoint as you suggested and the exception was thrown straight away.
Your breakpoint should have been hit first. It shouldn't have thrown an exception first. This suggests that your cbxCategoryBFill() is never called. That would explain why the DisplayMember and ValueMember don't seem to be working on that second combobox.
 

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
Update
Your breakpoint should have been hit first. It shouldn't have thrown an exception first. This suggests that your cbxCategoryBFill() is never called. That would explain why the DisplayMember and ValueMember don't seem to be working on that second combobox.
Based on what you said, I've just moved the methods from 'form_load' to under 'InitializeComponent' and now I don't get the exception but the filter is not working on the third combo.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
6,068
Location
Chesapeake, VA
Programming Experience
10+
Set a breakpoint on cbxCat3_SelectedIndexChanged(). Inspect the value of cbxCat3.Text. Is it a reasonable value? If so, then that's the actual results of your filter.
 
Last edited:

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
Set a breakpoint on cbxCat3_SelectedIndexChanged(). Inspect the value of cbxCat3.Text. Is it a reasonable value? If so, then that's the actual results of your filter.
We're in business.
Was my main problem here the fact that form_Load is a private void?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
6,068
Location
Chesapeake, VA
Programming Experience
10+
No.

It's the sequence of events. The constructor creates the form and stages various settings for the controls that will show up on the form. The load event is fired before the form is shown, but after controls have actually been created from the point of view of Windows. At that point in time, events start getting fired off, including when items are added to controls or selected items change within the controls as items are added. Since your selected item change events were dependent on the controls having the correct display members and value members set, then things went awry.
 

Daz66

Member
Joined
May 17, 2020
Messages
22
Programming Experience
Beginner
No.

It's the sequence of events. The constructor creates the form and stages various settings for the controls that will show up on the form. The load event is fired before the form is shown, but after controls have actually been created from the point of view of Windows. At that point in time, events start getting fired off, including when items are added to controls or selected items change within the controls as items are added. Since your selected item change events were dependent on the controls having the correct display members and value members set, then things went awry.
I have a lot to learn, but It's great fun.
Thanks for sticking with me, your efforts have been greatly appreciated.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,755
Location
Sydney, Australia
Programming Experience
10+
God I love straight talk! :).
It's a personal app for work so there's just me using it so far, but who knows, If I keep practicing hard and getting good advice like this. (y)
I see this particular thing quite often and it always annoys me. It seems to be a "because I can" sort of thing that doesn't actually achieve anything useful. No one who knows anything about using GUI software needs it pointed out that they should select an item from a drop-down and anyone who does need to be told that needs far more help than just that. You can obviously do what you want but the number of people who do this pointless thing and end up making life hard for themselves as a result is amazing.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
6,068
Location
Chesapeake, VA
Programming Experience
10+
And furthermore, on any decent desktop GUI framework, as well as any modern web UI backed by JavaScript, and modern phone GUIs, you can detect whether the user has selected an item within a list. It was only the older web-based UI before the dominance of JavaScript that needed combo boxes where there was a placeholder value for "no selection made". This was because in the older web-based UI, there was no easy way to communicate from the HTML control back to the web server that the user had not touched the combo box and not selected anything. With modern GUIs, you can enforce that the user has made a selection since you can watch every move they make and keep track of what they have done.
 
Top Bottom