【问题标题】:Search bar in Tabbed page title view -xamarin forms选项卡式页面标题视图中的搜索栏 -xamarin 表单
【发布时间】:2020-03-31 01:57:28
【问题描述】:

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

我的标签页

<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>

【问题讨论】:

  • 在 Xamarin Forms 中实现似乎并不容易,也许您可​​以尝试在 Native Android 中使用自定义 TabPage。如果有其他好的解决方案会在这里分享。
  • @JuniorJiang-MSFT 谢谢
  • 您好,我在 Xamarin Forms 中找到了解决方案并更新了答案,您有时间可以看看。 :)

标签: xamarin.forms


【解决方案1】:

您可以使用 MessagingCenter 来实现它。在每个 Tab Page 中,当SearchBarTextChangeed 发送消息给ViewModel 以更改模型数据。

关于标签页

<?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>

在 One Page 中,其 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 供参考。

【讨论】:

  • @AndroDevil Okey,如果回答对我有帮助,请告诉我 :) 圣诞快乐!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-10
相关资源
最近更新 更多