【问题标题】:How to add Picker above a CollectionView如何在 CollectionView 上方添加 Picker
【发布时间】:2020-07-16 21:29:48
【问题描述】:

我是 Xamarin.Forms 开发的新手,如果这是一个基本问题,我深表歉意。 下面是 Xamarin.Forms Master-Detail 页面“ItemsPage.xaml”的开箱即用代码

我想在动态显示的项目列表上方添加一个选择器。
问题 1) 我应该插入什么 XAML 来添加 Picker?我尝试了一些变体,但 xaml 一直在抱怨。

当用户在 Pickerm 中选择一个选项时,我想过滤 CollectionView 中显示的列表以仅显示用户在 Picker 中选择的类型的项目。 问题 2) 我将如何设置 onchange 行为以将过滤器应用于显示的列表?

感谢您提前提供任何建议或示例代码!


<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="NB_App.Views.ItemsPage"
             Title="{Binding Title}"
             x:Name="BrowseItemsPage">

    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
    </ContentPage.ToolbarItems>


    <!-- This is where I want to insert the Picker -->

    <RefreshView IsRefreshing="{Binding IsBusy, Mode=TwoWay}" Command="{Binding LoadItemsCommand}">

        <CollectionView x:Name="ItemsCollectionView" ItemsSource="{Binding Items}" >
            <CollectionView.ItemTemplate>

【问题讨论】:

  • 要向任何页面添加多个子元素,您需要使用 StackLayout、Grid 等布局容器

标签: xaml xamarin xamarin.forms


【解决方案1】:

当 Picker 引发 SelectedIndexChanged 事件时,您将绑定 CollectionView 的 ItemsSource

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App9.MainPage">


    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
    </ContentPage.ToolbarItems>
    <StackLayout>
        <Picker Title="My Picker" SelectedIndexChanged="Picker_SelectedIndexChanged">
            <Picker.Items>
                <x:Array>
                    <x:String>A</x:String>
                    <x:String>B</x:String>
                    <x:String>C</x:String>
                    <x:String>D</x:String>
                </x:Array>
            </Picker.Items>
        </Picker>
        <!-- This is where I want to insert the Picker -->
        <RefreshView IsRefreshing="{Binding IsBusy, Mode=TwoWay}" Command="{Binding LoadItemsCommand}">

            <CollectionView x:Name="ItemsCollectionView"  />
        </RefreshView>
    </StackLayout>
</ContentPage>

后面的代码

        private void Picker_SelectedIndexChanged(object sender, EventArgs e)
        {
            var picker = sender as Picker;
            switch (picker.SelectedIndex)
            {
                case 0:
                    ItemsCollectionView.ItemsSource = new ObservableCollection<string>() { "apple", "america"};
                    break;
                case 1:
                    ItemsCollectionView.ItemsSource = new ObservableCollection<string>() { "ball", "basket" };
                    break;
                case 2:
                    ItemsCollectionView.ItemsSource = new ObservableCollection<string>() { "cat", "coronavirus" };
                    break;
                case 3:
                    ItemsCollectionView.ItemsSource = new ObservableCollection<string>() { "dog", "disease" };
                    break;
                default:
                    break;
            }
        }

您也可以通过带有命令的 MVVM 执行此操作。由于您是新手,代码背后的方法应该有助于学习它。

【讨论】:

    【解决方案2】:

    根据你的描述,你想添加 Picker 来选择 item 来过滤 Collectionview,对吗?

    如果是,我做一个样本,你可以看看:

    <ContentPage
    x:Class="demo3.collectionviewsample.Page2"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <ContentPage.Content>
        <StackLayout>
            <Picker
                ItemDisplayBinding="{Binding .}"
                ItemsSource="{Binding FilterOptions}"
                SelectedItem="{Binding SelectedFilter}" />
            <CollectionView ItemsSource="{Binding FilterSource}">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
    
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding Name}" />
                            <Label Text="{Binding Role}" />
                        </StackLayout>
    
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
    </ContentPage.Content>
    

     public partial class Page2 : ContentPage
    {
        public Page2()
        {
            InitializeComponent();
            this.BindingContext = new ItemViewModel();
        }
    }
    

    视图模型:

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }     
        public string Role { get; set; }
    }
    
    public class ItemViewModel:ViewModelBase
    {
        public ObservableCollection<string> FilterOptions { get; set; }
        public ObservableCollection<Item> source { get; set; }
    
    
        public List<Item> _FilterSource;
        public List<Item> FilterSource
        {
            get { return _FilterSource; }
            set
            {
                _FilterSource = value;
                RaisePropertyChanged("FilterSource");
            }
        }
    
        private string _SelectedFilter;
        public string SelectedFilter
        {
            get { return _SelectedFilter; }
            set
            {
                _SelectedFilter = value;
                RaisePropertyChanged("SelectedFilter");
                filteritems(SelectedFilter);
            }
        }
    
    
        public ItemViewModel()
        {
            FilterOptions = new ObservableCollection<string>()
            {
                "All",
                "Admin",
                "Editor",
                "Student"
            };
    
            source = new ObservableCollection<Item>()
            {
                new Item() { Id = 1, Name = "cherry", Role = "Admin" },
                new Item() { Id = 2, Name = "barry", Role = "Admin" },
                new Item() { Id = 3, Name = "json", Role = "Editor" },
                new Item() { Id = 3, Name = "json", Role = "Editor" },
                new Item() { Id = 5, Name = "Leo", Role = "Student" },
                new Item() { Id = 6, Name = "Cole", Role = "Student" }
            };
    
    
            FilterSource = new List<Item>();
        }
    
        private void filteritems(string selecteditem)
        {
            FilterSource.Clear();
            if(selecteditem=="All")
            {
                FilterSource = source.ToList();
            }
            else
            {
                FilterSource = source.Where(item => item.Role == selecteditem).ToList();
            }
    
        }
    }
    

    ViewModelBase 是实现 INotifyPropertyChanged 接口的类,用于通知数据发生变化。

    public class ViewModelBase : INotifyPropertyChanged
    {
    
        public event PropertyChangedEventHandler PropertyChanged;
    
    
        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    截图:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多