【问题标题】:How can I filter a picker by the selected item of another picker in Xamarin.Forms?如何通过 Xamarin.Forms 中另一个选择器的选定项过滤选择器?
【发布时间】:2020-01-11 21:27:09
【问题描述】:

我将数据存储在 Xamarin.Forms 应用程序的 SQLite 数据库中,如下所示:

  1. 一个
  2. 一个
  3. 一个
  4. 一个
  5. B
  6. B
  7. B
  8. C

等等。等等。

两列,一列作为不同的值列表,另一列作为“类别”。我有一个带有类别的选择器,我想做的就是选择一个类别,然后只在第二个选择器中显示该类别中的值。例如。在 Picker 1 中选择“B”将 Picker 2 的选项过滤为 5、6 和 7。我为 Picker 1 的 SelectedIndexChanged 设置了一个事件处理程序,但我只是不知道将什么设置为 Picker 2 的 ItemsSource SQLite。

编辑:找到解决方案,发布以供将来参考。此代码在 Picker 1 的已创建事件处理程序中运行。

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);
            }

        }

【问题讨论】:

    标签: c# sqlite xaml xamarin.forms


    【解决方案1】:

    我强烈建议您一次检索所有数据,而不是每次都选择 Picker1,再次查询数据库,然后再次填充 Picker2。 这将在很大程度上取决于网络并影响交互性。

    所以,我们可以根据我们的数据结构一次得到所需的数据。

    我创建了一个简单的demo来模拟这个功能,主要代码是:

    ValueModel

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

    班级CategoryModel

     public class CategoryModel
    {
        public string CategoryName { get; set; }
    
        public ObservableCollection<ValueModel> values { get; set; }
    
        public CategoryModel()
        {
            values = new ObservableCollection<ValueModel>();
        }
    }
    

    班级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;
        }
    }
    

    结果是:

    【讨论】:

    • 这很有帮助,但是有什么方法可以做到这一点,而无需为每个值手动创建一个新的 CategoryModel?我的实际数据的类别比 A、B、C 多得多,并且有接近 700 个值的地方,因此手动执行此操作根本不是很有效。再次感谢。
    • 最好的方法是在服务器后端处理逻辑,通过API直接将需要的数据返回给客户端,这是最常用的方法之一。而我们也不需要为每个值手动创建一个新的 CategoryModel。
    【解决方案2】:

    您可以使用 LINQ 并根据 Picker 1 的 Selected 值过滤 Picker 2 的项目

    您可以在 Picker 1 的 SelectedIndexChanged 中处理这个问题:

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

    【讨论】:

    • 谢谢你,但是我的 SelectedIndexChanged 事件处理程序似乎不包含 SelectedItem 的定义?
    • 查看答案,使用 Picker1.SelectedItem 而不是 e.SelectedItem。
    猜你喜欢
    • 2023-03-22
    • 2016-10-31
    • 2020-07-21
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    相关资源
    最近更新 更多