![](/img/trans.png)
[英].NET MAUI - Error with shell navigation with dictionary as parameter
[英]Maui Shell backwards navigation
我希望用戶能夠將產品從一個位置移動到另一個位置。 完成后,我想 go 返回產品頁面,因為他可能會繼續從同一位置移動產品。 我有兩個略有不同的場景。
場景 1:
//SourceAisle/SourceLocation/Products/TargetAisle/TargetLocation
場景 2:
//SourceAisle/SourceLocation/Products/FavoriteLocation
在這兩種情況下,當用戶完成后,我想 go 回到
//SourceAisle/SourceLocation/Products
我可以在場景 1 中執行Shell.Current.GoToAsync("../..")
,在場景 2 中Shell.Current.GoToAsync("..")
但我希望有一些共享邏輯,即go 返回產品頁。
根據文檔,可以使用/route或///route向后搜索,但我不確定我是否理解它是如何工作的。 我不想“推送”任何新頁面,我基本上想“彈出”所有頁面直到我想要顯示的頁面。
是否可以使用 Shell 導航?
筆記
我在一個舊的 Xamarin 項目中創建了一個擴展方法,它完全按照上面的方式執行,但如果 Shell 提供了一種本地方法,我不想使用它。
// await Shell.Current.Navigation.PopToAsync<ProductsPage>();
internal static class NavigationExtensions
{
private static readonly SemaphoreSlim _semaphore = new (1, 1);
public static async Task PopToAsync<T>(this INavigation nav, Page nextPage = null, bool animated = true) where T : Page
{
await _semaphore.WaitAsync();
try
{
bool exists = nav.NavigationStack
.Where((p, i) => i <= nav.NavigationStack.Count - 2)
.Any(p => p is T);
if (!exists)
throw new ArgumentException($"The specified page {typeof(T).Name} does not exist in the stack");
for (var index = nav.NavigationStack.Count - 2; index > 0; index--)
{
if (nav.NavigationStack[index] is T)
break;
nav.RemovePage(nav.NavigationStack[index]);
}
if (nextPage is not null)
nav.InsertPageBefore(nextPage, nav.NavigationStack[nav.NavigationStack.Count - 1]);
await nav.PopAsync(animated);
}
finally
{
_semaphore.Release();
}
}
}
編輯
AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MyApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MyApp.Views">
<FlyoutItem Route="SourceAisle" Title="Stock Movement">
<ShellContent ContentTemplate="{DataTemplate views:AislesPage}" />
</FlyoutItem>
</Shell>
AppShell.xaml.cs
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute("SourceAisle", typeof(AislesPage));
Routing.RegisterRoute("SourceLocation", typeof(LocationsPage));
Routing.RegisterRoute("Products", typeof(ProductsPage));
Routing.RegisterRoute("TargetAisle", typeof(AislesPage));
Routing.RegisterRoute("TargetLocation", typeof(LocationsPage));
Routing.RegisterRoute("FavoriteLocation", typeof(FavoritesPage));
}
}
通道和位置頁面用於源和目標,並且有一些 state 來處理這兩種不同的情況,但這不在這個問題的 scope 中。
從 LocationsViewModel 我調用await Shell.Current.GoToAsync("Products")
,從 ProductsViewModel 我調用await Shell.Current.GoToAsync("TargetAisle")
等等。 我認為這就是所謂的相對路由而不是絕對路由,不確定我是否應該做不同的事情。
您可以編寫這樣的命令,它可以識別頁面名稱,然后導航到目標頁面。
public class MyViewModel: ContentPage
{
public ICommand NavigateCommand { get; private set; }
public MyViewModel()
{
NavigateCommand = new Command<Type>(
async (Type pageType) =>
{
Page page = (Page)Activator.CreateInstance(pageType);
await Navigation.PushAsync(page);
});
}
}
這是命令的樣式。
<TextCell Text="Entry"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type views:CustomizeSpecificEntryPage}" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.