选项卡式页面标题视图-xamarin形式中的搜索栏

时间:2019-12-06 04:36:33

标签: xamarin.forms

我有一个使用选项卡式页面的xamarin.forms应用程序。选项卡式页面的子级是两个内容页面。两个内容页面中的每个页面都有一些列表。我想在选项卡式页面标题视图中添加搜索栏。我可以将其添加为选项卡页面的titleview。但是,如何使用单个搜索栏在子页面中搜索两个不同的列表?

我的标签页

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"      
             xmlns:Views="clr-namespace:Sample.Views"
             BarBackgroundColor="{DynamicResource NavigationBarColor}"
             mc:Ignorable="d"
             SelectedTabColor="White"          
             UnselectedTabColor="LightGray"
             NavigationPage.HasNavigationBar="True"                  
             x:Class="Sample.Views.TimeSheetsTab">
    <NavigationPage.TitleView>
        <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" >
            <Label FontSize="Medium" Text="Timesheets" HorizontalTextAlignment="Start"  VerticalTextAlignment="Center" TextColor="{DynamicResource SecondaryTextColor}"></Label>
            <SearchBar  HorizontalOptions="EndAndExpand"  Margin="0,2,10,2">

            </Image>
        </StackLayout>
    </NavigationPage.TitleView>
    <TabbedPage.Children>
        <Views:PendingTimesheets Title="Pending" IconImageSource="icon_pending.png"/>
        <Views:ApprovedTimesheets Title="Approved" IconImageSource="icon_approved.png"/>
    </TabbedPage.Children>
</TabbedPage>

enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

您可以使用 MessagingCenter 来实现它。在每个标签页中,当SearchBar TextChangeed发送消息到ViewModel时,以更改模型数据。

关于 TabbedPage

<?xml version="1.0" encoding="utf-8"?>
<TabbedPage 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" xmlns:views="clr-namespace:TabbedPageDemo.Views" x:Class="TabbedPageDemo.Views.MainPage">
    <TabbedPage.Children>
        <NavigationPage Title="Browse">
            <NavigationPage.Icon>
                <OnPlatform x:TypeArguments="FileImageSource">
                    <On Platform="iOS" Value="tab_feed.png" />
                </OnPlatform>
            </NavigationPage.Icon>
            <x:Arguments>
                <views:ItemsPage />
            </x:Arguments>
        </NavigationPage>
        <NavigationPage Title="About">
            <NavigationPage.Icon>
                <OnPlatform x:TypeArguments="FileImageSource">
                    <On Platform="iOS" Value="tab_about.png" />
                </OnPlatform>
            </NavigationPage.Icon>
            <x:Arguments>
                <views:AboutPage />
            </x:Arguments>
        </NavigationPage>
    </TabbedPage.Children>
</TabbedPage>

在一页中,其ViewModel需要Subscribe MessageCenter:

public class ItemsViewModel : BaseViewModel
{

    public ObservableCollection<Item> Items { get; set; }
    //Use FilteredItems to show the Filtered Items on ListView
    public ObservableCollection<Item> filteredItems;
    public ObservableCollection<Item> FilteredItems
    {
        get { return filteredItems; }
        // Use SetProperty to refresh the ListView ItemsSource
        set { SetProperty<ObservableCollection<Item>>(ref filteredItems, value); }
    }

    public Command LoadItemsCommand { get; set; }

    public ItemsViewModel()
    {
        Title = "Browse";
        Items = new ObservableCollection<Item>();
        FilteredItems = new ObservableCollection<Item>();
        LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());

        MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
        {
            var newItem = item as Item;
            Items.Add(newItem);
            FilteredItems.Add(newItem);
            await DataStore.AddItemAsync(newItem);
        });
        //use FilterItems Message to filter the text
        MessagingCenter.Subscribe<ItemsPage, TextChangedEventArgs>(this, "FilterItems", async (obj, e) =>
        {
            string filterText = e.NewTextValue;
            var Filtered=Items.Where<Item>(item => item.Text.ToLower().Contains(filterText));
            if (Filtered != null)
            {
                //If the filter result is not null, we will update the itemssource to a new array
                FilteredItems = new ObservableCollection<Item>(Filtered);
            }
            else
            {
                filteredItems = new ObservableCollection<Item>();
            }

        });

    }

    async Task ExecuteLoadItemsCommand()
    {
        if (IsBusy)
            return;

        IsBusy = true;

        try
        {
            Items.Clear();
            var items = await DataStore.GetItemsAsync(true);
            foreach (var item in items)
            {
                Items.Add(item);
                FilteredItems.Add(item);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

}

一页的Xaml:

<?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="TabbedPageDemo.Views.ItemsPage" Title="{Binding Title}" x:Name="BrowseItemsPage">
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
    </ContentPage.ToolbarItems>
    <NavigationPage.TitleView>
                <SearchBar x:Name="sbSearch" WidthRequest="500" HeightRequest="100" />
    </NavigationPage.TitleView>
    <StackLayout>
        <ListView x:Name="ItemsListView" ItemsSource="{Binding FilteredItems}" VerticalOptions="FillAndExpand" HasUnevenRows="true" RefreshCommand="{Binding LoadItemsCommand}" IsPullToRefreshEnabled="true" IsRefreshing="{Binding IsBusy, Mode=OneWay}" CachingStrategy="RecycleElement" ItemSelected="OnItemSelected">
            <d:ListView.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>First Item</x:String>
                    <x:String>Second Item</x:String>
                    <x:String>Third Item</x:String>
                    <x:String>Fourth Item</x:String>
                    <x:String>Fifth Item</x:String>
                    <x:String>Sixth Item</x:String>
                </x:Array>
            </d:ListView.ItemsSource>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="10">
                            <Label Text="{Binding Text}" d:Text="{Binding .}" LineBreakMode="NoWrap" Style="{DynamicResource ListItemTextStyle}" FontSize="16" />
                            <Label Text="{Binding Description}" d:Text="Item description" LineBreakMode="NoWrap" Style="{DynamicResource ListItemDetailTextStyle}" FontSize="13" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

当SearchBar TextChanged时,发送消息:

    private void SbSearch_TextChanged(object sender, TextChangedEventArgs e)
    {
        MessagingCenter.Send<ItemsPage, TextChangedEventArgs>(this, "FilterItems", e);

    }

这里是Sample Link供参考。