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
提前感谢您的帮助。几天来我正在开发一个 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