简体   繁体   中英

How can I filter a picker by the selected item of another picker in Xamarin.Forms?

I have data stored in a SQLite database in my Xamarin.Forms app that looks like this:

  1. A
  2. A
  3. A
  4. A
  5. B
  6. B
  7. B
  8. C

etc. etc.

Two columns, one as a distinct list of values and the other as a "category". I have a picker with the categories, and all I'd like to be able to do is select a category, then only show the values in that category in a second picker. Eg selecting "B" in Picker 1 filters Picker 2's options to be 5, 6, and 7. I have an event handler set up for SelectedIndexChanged of Picker 1, but I just don't know what to set as Picker 2's ItemsSource in terms of SQLite.

EDIT: Found a solution, posting for future reference. This code works out of Picker 1's created event handler.

private void Picker1_SelectedIndexChanged(object sender, EventArgs e)
        {
            using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
            {
                var assets = conn.Table<Values>();
                Picker2.ItemsSource = conn.Query<Values>("select * from Values where Category = ?", Picker1.SelectedItem);
            }

        }

I strongly recommend that you retrieve all the data at once, rather than selecting Picker1 every time, querying the database once more, and populating Picker2 again. This will depend heavily on the network and affect interactivity.

So, we can get the required data at once according our data struct.

I created a simple demo to simulate the function,the main code is:

class ValueModel

public  class ValueModel
{
    public string ValueName { get; set; }
}

class CategoryModel

 public class CategoryModel
{
    public string CategoryName { get; set; }

    public ObservableCollection<ValueModel> values { get; set; }

    public CategoryModel()
    {
        values = new ObservableCollection<ValueModel>();
    }
}

class CategoryViewModel

public class CategoryViewModel
{
    public ObservableCollection<CategoryModel> Categories { get; set; }

    public CategoryViewModel()
    {
        Categories = new ObservableCollection<CategoryModel>();
    }
}

MainPage.xaml

   <StackLayout>
    <Picker Title="select category" x:Name="CategoryPicker" ItemsSource="{Binding Categories}" ItemDisplayBinding="{Binding CategoryName}" SelectedIndexChanged="DiameterPicker_SelectedIndexChanged"></Picker>
    <Picker Title="select value" x:Name="ValuePicker" ItemDisplayBinding="{Binding ValueName}"></Picker>
   </StackLayout>

MainPage.xaml.cs

 public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        var categories = new ObservableCollection<CategoryModel>() {
            new CategoryModel{CategoryName="A",values= {new ValueModel{ ValueName="1" }, new ValueModel { ValueName = "2" }, new ValueModel { ValueName = "3" } ,new ValueModel{ ValueName="4"}} },
             new CategoryModel{CategoryName="B",values= {new ValueModel{ ValueName="5" }, new ValueModel { ValueName = "6" }, new ValueModel { ValueName = "7" } } }
        };

        CategoryViewModel categoryViewModel = new CategoryViewModel();
        categoryViewModel.Categories = categories;

        BindingContext = categoryViewModel;

    }

    private void DiameterPicker_SelectedIndexChanged(object sender, EventArgs e)
    {
        CategoryViewModel viewModel = BindingContext as CategoryViewModel;
        ValuePicker.ItemsSource = viewModel.Categories[((Picker)sender).SelectedIndex].values;
    }
}

The result is:

在此处输入图片说明

You can use LINQ and filter the items for the Picker 2 based on the Selected value of Picker 1

You can handle this in SelectedIndexChanged of Picker 1:

Picker2.ItemSource = db.Query<TableName>().ToList().Where(x => x.Property == e.SelectedItem).

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