问题是,当我单击通知历史记录页面上的通知时,导航动画会在导航到详细信息页面之前显示导航回主页。当我从详细信息页面导航回来时,而不是返回通知列表,它直接进入主页。
AppShell.xaml 中的弹出项:
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="tab_about.png"
Route="AboutPage" />
<ShellContent
Title="Browse"
ContentTemplate="{DataTemplate local:ItemsPage}"
Icon="tab_feed.png" />
<ShellContent
Title="Main"
ContentTemplate="{DataTemplate local:MainPage}"
Icon="tab_feed.png" />
</FlyoutItem>
在 Shell 子类构造函数中的 Routing.RegisterRoute 方法:
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute("NotificationHistory", typeof(NotificationHistory));
Routing.RegisterRoute("NotificationDetails", typeof(NotificationDetails));
}
从 MainPage 导航到 NotificationHistory 页面。
private async void btn1_Clicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("NotificationHistory");
}
从 NotificationHistory 导航到 NotificationDetailspage。
async void OnItemSelected(Item item)
{
if (item == null)
return;
// This will push the ItemDetailPage onto the navigation stack
await Shell.Current.GoToAsync($"{nameof(ItemDetailPage)}?{nameof(ItemDetailViewModel.ItemId)}={item.Id}");
}
通知历史页面:
<StackLayout>
<CollectionView
x:Name="ItemsListView"
ItemsSource="{Binding Items}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10" x:DataType="model:Item">
<Label
FontSize="16"
LineBreakMode="NoWrap"
Text="{Binding Text}" />
<Label
FontSize="13"
LineBreakMode="NoWrap"
Text="{Binding Description}" />
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type local:HistoryViewModel}}, Path=ItemTapped}"
CommandParameter="{Binding .}"
NumberOfTapsRequired="1" />
</StackLayout.GestureRecognizers>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
public partial class NotificationHistory : ContentPage
{
HistoryViewModel _viewModel;
public NotificationHistory()
{
InitializeComponent();
BindingContext = _viewModel = new HistoryViewModel();
}
}
public class HistoryViewModel : BaseViewModel
{
public ObservableCollection<Item> Items { get; set; }
public Command<Item> ItemTapped { get; }
public HistoryViewModel()
{
Title = "history";
Items = new ObservableCollection<Item>()
{
new Item { Id ="1" , Text = "First item", Description="This is an item description." },
new Item { Id = "2", Text = "Second item", Description="This is an item description." },
new Item { Id = "3", Text = "Third item", Description="This is an item description." },
new Item { Id = "4", Text = "Fourth item", Description="This is an item description." },
new Item { Id = "5", Text = "Fifth item", Description="This is an item description." },
new Item { Id = "6", Text = "Sixth item", Description="This is an item description." }
};
ItemTapped = new Command<Item>(OnItemSelected);
}
async void OnItemSelected(Item item)
{
if (item == null)
return;
// This will push the ItemDetailPage onto the navigation stack
await Shell.Current.GoToAsync($"{nameof(NotificationDetails)}?{nameof(DetailViewModel.ItemId)}={item.Id}");
}
}
通知详情页面:
<StackLayout Padding="15" Spacing="20">
<Label FontSize="Medium" Text="Text:" />
<Label FontSize="Small" Text="{Binding Text}" />
<Label FontSize="Medium" Text="Description:" />
<Label FontSize="Small" Text="{Binding Description}" />
</StackLayout>
public partial class NotificationDetails : ContentPage
{
public NotificationDetails()
{
InitializeComponent();
this.BindingContext =new DetailViewModel();
}
}
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public class DetailViewModel : BaseViewModel
{
private string itemId;
private string text;
private string description;
public string Id { get; set; }
public string Text
{
get => text;
set => SetProperty(ref text, value);
}
public string Description
{
get => description;
set => SetProperty(ref description, value);
}
public string ItemId
{
get
{
return itemId;
}
set
{
itemId = value;
LoadItemId(value);
}
}
public async void LoadItemId(string itemId)
{
HistoryViewModel items = new HistoryViewModel();
try
{
var item = items.Items.Where(x => x.Id == itemId).FirstOrDefault();
if(item!=null)
{
Id = item.Id;
Text = item.Text;
Description = item.Description;
}
}
catch (Exception)
{
Debug.WriteLine("Failed to Load Item");
}
}
}
BaseViewModel 是实现 INotifyPropertyChanged 的类
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName] string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}