简体   繁体   中英

How do I filter from XML(in a listBox) using a combobox?

I need to write a switch statement that filters my XML data by using a combo box. I would like to add(at somepoint) a second combobox to filter with. I am having real difficulty figuring this out and have come seeking help. The application is a small animal rescue application. I would like to filter by(combobox1) "All", "Dog", and "Cat". And eventually add in "Baby", "Adult", and "Senior" as a second combobox.

Here is what my XML looks like:

<?xml version="1.0" encoding="utf-8"?>
<Animals>
 <Animal>
  <Name>Bruce</Name>
  <Type>Dog</Type>
  <Age>Adult</Age>
 </Animal>
 <Animal>
  <Name>Gizmo</Name>
  <Type>Cat</Type>
  <Age>Senior</Age>
 </Animal>
</Animals>

If it matters, this is how I populate my listBox from the xml document(this would also be the "All" above):

var an = XElement.Load(@"Animals.xml")
            .Descendants("Animal")
            .OrderBy(xe => (xe.Element("Name").Value))
            .ToList<XElement>();

        lstAnimals.Items.Clear();

        foreach (var a in an)
            lstAnimals.Items.Add(new Animal()
            {
                name = a.Element("Name").Value.ToString(),
                type = a.Element("Type").Value,
                age = a.Element("Age").Value
            });

I can't figure out how to filter them and how to word it in the switch statement. How can I set up this switch and filter? Any help would be appreciated. Hopefully I have asked this question right. :)

Add two combobox in your application,and set items for each combobox.Then handle combobox2 SelectedValueChanged event like this:

    private void comboBox2_SelectedValueChanged(object sender, EventArgs e)
    {
        string type = comboBox1.Text;
        string age = comboBox2.Text;

        var an = XElement.Load(@"Animals.xml")
        .Descendants("Animal")
        .Where(a=>a.Element("Type").Value == type && a.Element("Age").Value == age)
        .OrderBy(xe => (xe.Element("Name").Value))
        .ToList<XElement>();
    }
      foreach (var a in an)
        lstAnimals.Items.Add(new Animal()
        {
            name = a.Element("Name").Value.ToString(),
            type = a.Element("Type").Value,
            age = a.Element("Age").Value
        });

ofcourse you have to validate combobox values,hopefully i answer your question right =)

Edit for switch

switch (comboBox1.Text)
        {
         case "All" :   //No conditions
            var an = XElement.Load(@"Animals.xml")
        .Descendants("Animal")
        .OrderBy(xe => (xe.Element("Name").Value))
        .ToList<XElement>();
                break;

            case "Dog":
                var an = XElement.Load(@"Animals.xml")
        .Descendants("Animal")
        .Where(a=>a.Element("Type").Value ="Dog")
        .OrderBy(xe => (xe.Element("Name").Value))
        .ToList<XElement>();
                break;

            case "Cat":
                var an = XElement.Load(@"Animals.xml")
        .Descendants("Animal")
        .Where(a=>a.Element("Type").Value ="Cat")
        .OrderBy(xe => (xe.Element("Name").Value))
        .ToList<XElement>();
                break;
        }

and you can use this logic for age

It seems ok. So, your list of animals has animal objects, which have name,type and age.
Here's some pseudo code and example:

What you want to do is fill the combobox, depending on another, which might have "all", "baby","adult" for example.

Your combobox populater will simply look at the SelectedItem of the "filter" combo box, and have a switch that will look like that:

if "all"
   { add all animals from list ... }
if "baby" 
   { use linq to add only babies ... }
... rinse and repeat

your linq might look like :

var valid = (from a in an
            where a.age == ("baby")
            select a);

and that should do the trick.


Assume the next XAML:

 <ComboBox Name="FirstCombo" Height="30" VerticalAlignment="Top" ItemsSource="{Binding Fico}"></ComboBox>
 <ComboBox Name="SecondCombo" Height="30" VerticalAlignment="Top" Grid.Column="1"  ItemsSource="{Binding Seco}"></ComboBox>

and the following code:

private void FillItems()
{
   Fico = new ObservableCollection<string> { "Animal one", "Animal two" , "Animal three"};
   Seco = new ObservableCollection<string> { "All", "Baby" };    
}
public ObservableCollection<string> Fico { get; set; }
public ObservableCollection<string> Seco { get; set; }

This creates 2 comboboxes, which have 3 animals, and 2 "options" to select: "all" and "baby".
You can hook the change event on the SecondCombo , so whenever it changes, you will refill the FirstCombo items, to hold the animals that fit the "filter" selected.

You can have as default the 1st entry ("all" in this example), or whatever you want (you can persist the option for saved users, and so on ...), and the first time, depending on which is selected, fill your animals list accordingly.


Also, here's a similar question about multiple combo boxes and linq.

尝试这个。

Var results=lstAnimals.Items.where(x=>(ComboBox1.SelectedItem=="All" ||x.type==ComboBox1.SelectedItem)  && x.Age==ComboBox2.SelectedNode)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM