Nan0
Nan0

Reputation: 61

Filtering ListBox using combobox and LINQ

I have a winform that includes a ListBox and a Combobox. In this ListBox appears a clients list on first run.

I want to filter the "Clients" in the ListBox with a Combobox.

To fill the ListBox using the string selected in the Combobox i'm using :

private void FillListBox()
{
    this.lstClient.Items.Clear();

    foreach (Client c in this.client)
    {
        if (this.cBox.Text == "All")
            this.lstClient.Items.Add(c.ToString());
        else
            if (this.cBox.Text == "Retail" && c.GetType() == typeof(RetailClient))
                this.lstClient.Items.Add(c.ToString());
    }

    this.lstClient.Sorted = true;
}

After that i call this method from the event of the ComboBox :

private void cBox_TextChanged(object sender, EventArgs e)
{
    this.FillListBox();
}

It works "great" but my code is not really dynamic and too long (lots of differents clients) that's why i would like to use LINQ. I read on microsoft's documentation but i'm pretty confused on how using it.

Does anyone have some times to show me the way ?

Adding infos :

My form :

Graphical

I select the type i want in the ComboBox :

ComboBox

The result :

Result

Thanks

Upvotes: 1

Views: 488

Answers (1)

Mong Zhu
Mong Zhu

Reputation: 23732

Ok let's give it a try. If you want to implement filtering you should think about a proper structure how to represent your filter criterion. In this case you have a label in your combobox which is bound to a unique filter criterion. This could be represented by a custom class:

public class SortingRepresentation
{
    public string DisplayLabel { get; set; }
    public Type ClientType { get; set; }        
}

Now you can create a List of those criteria and shove it into the combobox:

List<SortingRepresentation> sortingFields = new List<SortingRepresentation>();

public Form1()
{
    sortingFields.Add(new SortingRepresentation{ DisplayLabel = "All", TypeCriterion = typeof(Client) });
    sortingFields.Add(new SortingRepresentation{ DisplayLabel = "Only Retail", TypeCriterion = typeof(Client_A) });
    sortingFields.Add(new SortingRepresentation{ DisplayLabel = "Only Wholesale", TypeCriterion = typeof(Client_B) });
    sortingFields.Add(new SortingRepresentation{ DisplayLabel = "Only Human Wholesale", TypeCriterion = typeof(Client_C) });

    cBox.DisplayMember = "DisplayLabel";
    cBox.DataSource = sortingFields;
}

When the selection changes in the combobox you can catch now the selected item (which will be of type SortingRepresentation and pass it as a filter to FillListBox:

private void cBox_SelectedIndexChanged(object sender, EventArgs e)
{
    FillListBox((SortingRepresentation)cBox.SelectedItem);
}

Now you can use the Type TypeCriterion inside this object to filter your list:

private void FillListBox(SortingRepresentation sortcriterion)
{
    this.lstClient.DataSource = null;

    this.lstClient.DataSource = client
            .Where(x => x.GetType() == sortcriterion.TypeCriterion || // either you are of this type
                        x.GetType().BaseType == sortcriterion.TypeCriterion // or your parent is of this type
                   ).ToList();
}

Since you are using a listbox, you can bind the sorted list directly to the DataSource and be done with it. For the proper display, you need to override the ToString method in your Client class and the ListBox will take care of the display accordingly. But as I see you've done it already

Upvotes: 1

Related Questions