【问题标题】:.NET MAUI - Multiple Shell.SearchHandler Possible?.NET MAUI - 多个 Shell.SearchHandler 可能吗?
【发布时间】:2022-10-07 09:07:49
【问题描述】:

我在选项卡式 MAUI 应用程序 (.NET 6) 中使用了 Shell.SearchHandler。我将我的应用程序启动到一个特定页面,您可以在其中通过 API 搜索一组“外部联系人”。我有一个额外的页面来再次通过 API 搜索一组系统用户。当应用程序初始化时。如果我导航到用户页面,它不会更新搜索处理程序,并且搜索功能仍在使用初始页面的模板。

是否可以修改每个页面上的模板?

ContactsPage.xaml

    <Shell.SearchHandler>
        <controls:ExternalContactSearchHandler Placeholder=\"Enter last name\"
                                  ShowsResults=\"true\"
                                  ItemTemplate=\"{StaticResource ExternalContactSearchTemplate}\"
                                  ExternalContacts=\"{x:Static data:ExternalContactData.ExternalContacts}\"
                                  SelectedItemNavigationTarget=\"{x:Type views:ContactDetailPage}\" />
    </Shell.SearchHandler>

用户.xaml

    <Shell.SearchHandler>
        <controls:UserSearchHandler Placeholder=\"Enter User Name\"
                                  ShowsResults=\"true\"
                                  ItemTemplate=\"{StaticResource UserSearchTemplate}\"
                                  Users=\"{x:Static data:UserData.Users}\"
                                  SelectedItemNavigationTarget=\"{x:Type views:UserDetailPage}\" />
    </Shell.SearchHandler>

应用程序.xaml

        <DataTemplate x:Key=\"UserSearchTemplate\">
            <Grid Padding=\"10\" 
                  ColumnDefinitions=\"0.15*,0.85*\">
                <Image Source=\"{Binding Images[1].ImageUri}\"
                       HeightRequest=\"40\"
                       WidthRequest=\"40\" />
                <Label Grid.Column=\"1\"
                       Text=\"{Binding Name}\"
                       FontAttributes=\"Bold\"
                       VerticalOptions=\"Center\" />
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key=\"ExternalContactSearchTemplate\">
            <Grid Padding=\"10\" ColumnDefinitions=\"Auto,Auto,Auto\">
                <Label Grid.Column=\"0\"
                       Text=\"{Binding FirstName}\"
                       FontAttributes=\"Bold\"
                       HorizontalOptions=\"Start\"
                       VerticalOptions=\"Center\" />
                <Label Grid.Column=\"1\"
                       Text=\"{Binding LastName}\"
                       FontAttributes=\"Bold\"
                       HorizontalOptions=\"Start\"
                       VerticalOptions=\"Center\" />
                <Label Grid.Column=\"2\"
                       Text=\"{Binding Title}\"
                       FontAttributes=\"Bold\"
                       HorizontalOptions=\"End\"
                       VerticalOptions=\"Center\" />
            </Grid>
        </DataTemplate>
  • 我没有使用过这个,但我认为你需要在 c# 中设置搜索处理程序而不是 xaml。见Consume a SearchHandler,下面的c#代码sn-p\"等效的 C# 代码是:\".
  • 感谢@ToolmakerSteve,但奇怪的是,当我在每个页面的构造函数中设置代码隐藏版本时,它似乎也不起作用。我(不幸地)认为我可能需要在导航时拆除并重建整个 Shell 资源,这令人沮丧且资源密集,但我至少知道我需要做什么。

标签: .net xaml search maui


【解决方案1】:

这当然很有趣,因为我假设在每个页面中设置 SearchHandler 可以解决这个问题,但是我将 Shell.SearchHandler XAML 移动到相应页面中的 C#(如下),它仍然只使用第一个使用的。我很困惑。我是否需要每次都从头开始重建整个 Shell?我并不反对在渲染之前将所有这些都转移到代码与 XAML 中,但这似乎没有必要,而且感觉就像我错过了一些东西。

用户.xaml.cs

    public UsersPage()
    {
        InitializeComponent();

        Shell.SetSearchHandler(this, new UserSearchHandler
        {
            Placeholder = "Enter first or last name",
            ShowsResults = true,
            SelectedItemNavigationTarget = typeof(UserDetailPage),
            Users = UserData.Users,
            ItemTemplate = new DataTemplate(() =>
            {
                Grid grid = new Grid { Padding = 10 };
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.15, GridUnitType.Star) });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.85, GridUnitType.Star) });

                Image image = new Image { HeightRequest = 40, WidthRequest = 40 };
                image.SetBinding(Image.SourceProperty, "Images[1].ImageUri");
                Label nameLabel = new Label { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center };
                nameLabel.SetBinding(Label.TextProperty, "Name");

                grid.Children.Add(image);
                grid.Children.Add(nameLabel);

                return grid;
            })
        });
    }

ContactsPage.xaml.cs

    public ContactsPage()
    {
        InitializeComponent();

        Shell.SetSearchHandler(this, new ExternalContactSearchHandler
        {
            Placeholder = "Enter search term",
            ShowsResults = true,
            SelectedItemNavigationTarget = typeof(UserDetailPage),
            ExternalContacts = ExternalContactData.ExternalContacts,
            ItemTemplate = new DataTemplate(() =>
            {
                Grid grid = new Grid { Padding = 10 };
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

                Label firstNameLabel = new Label { FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Center };
                firstNameLabel.SetBinding(Image.SourceProperty, "FirstName");
                Label lastNameLabel = new Label { FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Center };
                lastNameLabel.SetBinding(Label.TextProperty, "LastName");
                Label titleLabel = new Label { FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.Center };
                titleLabel.SetBinding(Label.TextProperty, "Title");

                grid.Children.Add(firstNameLabel);
                grid.Children.Add(lastNameLabel);
                grid.Children.Add(titleLabel);

                return grid;
            })
        });
    }

【讨论】:

    【解决方案2】:

    Shell.SetSearchHandler 影响所有的壳。它是全球性的。当您调用它时,所有页面都会受到影响。

    把它放在构造函数无效,因为在加载 Shell 时调用了构造函数:所有页面都被“构造”,即使是那些还不可见的页面。

    将以Shell.SetSearchHandler... 开头的代码移动到每个页面的OnAppearing 方法中。当该页面即将变得可见时运行:

    protected override void OnAppearing(...)
    {
        base.OnAppearing();
    
        Shell.SetSearchHandler...
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-02
      • 2021-11-16
      • 2022-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-27
      • 2023-01-12
      相关资源
      最近更新 更多