Xamarin.Forms Shell 在代码隐藏中生成热门点击页面

Xamarin.Forms Shell generate a Top Tapped Page in Code behind

提前感谢您的帮助。几天来我正在开发一个 Forms Shell 应用程序。我的 UI 在很多方面都是数据驱动的,我想要完成的是一个页面,该页面根据它拥有的模型在 tob 上显示多个选项卡。

换句话说,我尝试完成与 Shells 演示应用程序相同的布局:

<FlyoutItem Route="animals"
            Title="Animals"
            FlyoutDisplayOptions="AsSingleItem">
    <Tab Title="Domestic"
         Route="domestic"
         Icon="paw.png">
        <ShellContent Route="cats"
                      Style="{StaticResource DomesticShell}"
                      Title="Cats"
                      Icon="cat.png"
                      ContentTemplate="{DataTemplate views:CatsPage}" />
        <ShellContent Route="dogs"
                      Style="{StaticResource DomesticShell}"
                      Title="Dogs"
                      Icon="dog.png"
                      ContentTemplate="{DataTemplate views:DogsPage}" />
    </Tab>
</FlyoutItem>

但从 FlyoutMenu 中现有的 link 开始。就像上面 "Domestic" 选项卡的级别一样,当导航到该级别时,它会创建两个或更多 Shell 个点击率最高的页面。

我知道我可以使用 TappedPage 作为 ShellContent,但是 TappedPages 的样式有点不同我想知道我是否可以使用 "native" Shell 功能来实现这一点。

我已经尝试过类似的方法:

ShellSection tab1 = new ShellSection
{
Title = "Tab1"
};
tab1.Items.Add(new ShellContent() { Title = "Test1", Content = new ContentPage() { Title = "Test1" } });
tab1.Items.Add(new ShellContent() { Title = "Test2", Content = new ContentPage() { Title = "Test2" } });
var current = AppShell.Current.CurrentItem;
current.Items.Add(tab1);

但这还在底部标签栏和弹出菜单中添加了另一个条目,这是我不想要的。

为了更清楚,我尝试用模型截图来解释它。

假设我们有以下国内条目的弹出菜单。

这个国内条目指向一个页面,该页面的视图模型提供了 collection 应该在选项卡中显示的数据。

如您所见,此页面在标题视图中提供了一个 Link,它会打开一个弹出窗口以更改所选元素,并且应该 refresh/change 显示的数据例如具有三个选项卡。

我希望现在更清楚了。

编辑:

到现在的评论让我更进了一步。使用以下代码,我完成了所需的顶部选项卡。

        var current = AppShell.Current.CurrentItem;
        var currentSection = current.CurrentItem;

        //currentSection.Items.Clear();
        currentSection.Items.Add(new CatsPage() { Title = "Tab1"} ); ;
        currentSection.Items.Add(new ShellContent() { Title = "Tab2", Content = new CatsPage() });

但还不够完美——在添加的页面中,按钮标签栏被隐藏了,有什么解决办法吗?

有人有建议吗?

您的意思是您想要通过隐藏代码实现与 Shell 演示应用程序相同的结构吗?

如果是,你可以试试这个:

在 AppShell.xaml.cs:

public AppShell()
    {
        InitializeComponent();
        FlyoutItem shellItem = new FlyoutItem() { Title = "Tab1" };
        Tab tab = new Tab();
        tab.Items.Add(new ShellContent() { Title = "Test1", Content = new Page1()});
        tab.Items.Add(new ShellContent() { Title = "Test2", Content = new Page2()});
        shellItem.Items.Add(tab);
        this.Items.Add(shellItem);
    }

AppShell.xaml :

<?xml version="1.0" encoding="UTF-8"?>
<Shell 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:local="clr-namespace:ShellDemo.Views"
   Title="ShellDemo"
   x:Class="ShellDemo.AppShell">

</Shell>

page1.xaml:

<ContentPage ...>
    <Shell.TitleView>
      <Button Text="change" Clicked="Button_Clicked"></Button>
    </Shell.TitleView>
     ...
</ContentPage>

在page1.xaml.cs:

private void Button_Clicked(object sender, EventArgs e)
    {
        Tab tab = new Tab();
        tab.Items.Add(new ShellContent() { Title = "Test3", Content = new ContentPage() { Title = "Test3" } });
        tab.Items.Add(new ShellContent() { Title = "Test4", Content = new ContentPage() { Title = "Test4" } });
        AppShell.Current.CurrentItem.Items.Clear();
        AppShell.Current.CurrentItem.Items.Add(tab);
    }

更新 1:

根据您上面的草图,您是否要在单击 titleview () 中的 link 后更改 TabbedPage 内容?

效果如下(每页都要加shell titileview,这里用按钮代替link):

更新1您只需更改选项卡的内容:

 private void Button_Clicked(object sender, EventArgs e)
    {
        Tab tab = (Tab)AppShell.Current.CurrentItem.CurrentItem;
        tab.Items.Clear();
        tab.Items.Add(new ShellContent() { Title = "Test3", Content = new ContentPage() { Title = "Test3" } });
        tab.Items.Add(new ShellContent() { Title = "Test4", Content = new ContentPage() { Title = "Test4" } });

    }

更新 2:

我下载了你的项目,测试it.It实际上并没有隐藏底部的Tab,你可以点击底部的Tab,看到它存在,但是它没有背景颜色,所以你添加 ShellContent

时,只需给它 Shell.Resources 中定义的 Style
 var current = AppShell.Current.CurrentItem;
 var currentSection = current.CurrentItem;
 currentSection.Items.Add(new ShellContent() { Title = "Test3", Content = new CatsPage(),Style = (Style)AppShell.Current.Resources["BearsShell"] }); ;
 currentSection.Items.Add(new ShellContent() { Title = "Test4", Content = new CatsPage(), Style = (Style)AppShell.Current.Resources["BearsShell"] });

此解决方案还包括 ContentTemplate 在代码中的用法:

AppShell.xaml

<?xml version="1.0" encoding="utf-8"?>
<Shell
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Namespace.To.AppShell.xaml.cs"
    FlyoutBehavior="True" />

AppShell.xaml.cs

public AppShell()
{
    this.InitializeComponent();

    var flyoutTabOne = new Tab()
    {
        Items =
        {
            new ShellContent
            {
                ContentTemplate = new DataTemplate(() => new YourPage()),
                Route = "Route.To.Your.Page",
                Title = "Your page title",
            },
        },
        Route = "Route.To.Your.Tab.One",
        Title = "Tab one title",
    };

    var flyoutItem = new FlyoutItem();
    flyoutItem.Items.Add(flyoutTabOne);

    this.Items.Add(flyoutItem);
}

ContentTemplate 的用法对于获得所有选项卡的延迟加载很重要。因此,我强烈建议尽可能使用 ContentTemplate,因为在开始的问题中(在 xaml 中)已经是这种情况。如果您对 ContentTemplate 的更多信息感兴趣,请阅读此文档:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/tabs#efficient-page-loading