我有一个按钮,可以将用户发送回他们原来的页面。
但是,单击按钮后,用户将返回到他们原来的可滚动视图,而不是屏幕顶部。我有一种感觉,这是由于
ScrollView
。
以下是逐步过程:
如何覆盖此设置并通过单击页面 B 上的按钮将用户发送到页面 A 的顶部?
PageBVM
[RelayCommand]
private async void OnNavigateBackToPageAView()
{
try
{
await Shell.Current.GoToAsync("///pageA",
new Dictionary<string, object>
{
{"pageA", pageA }
});
}
catch (Exception ex)
{
Debug.WriteLine($"Error navigation back to page A view: {ex.Message}");
if (ex.InnerException != null)
{
Debug.WriteLine($"Inner Exception: {ex.InnerException.Message}");
}
}
}
PageA.xaml
<Grid>
<!-- Scrollable Content -->
<ScrollView>
<VerticalStackLayout>
</VerticalStackLayout>
</ScrollView>
</Grid>
PageA.xaml.cs
public partial class PageAView: ContentPage
{
{
InitializeComponent();
BindingContext = vm;
}
}
这样做在时间上有点棘手,因为需要先完全计算布局,然后才能执行类似
scrollView.ScrollToAsync(0, 0, false)
的操作。但是,通过触发 NavigatedTo
事件,然后在现有消息队列的末尾使用调度操作,您应该看到可靠的计时。还展示了一种后备方法,涉及几毫秒的“神奇延迟”,但我们会尽力避免这种情况。
我将在评论中发布我用来测试这个答案的完整代码,您可以确保它对您有效。
public partial class PageAView : ContentPage
{
public PageAView() => InitializeComponent();
private async void OnFwdNavClicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("///PageB");
}
protected async override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
#if true
Dispatcher.Dispatch(async () =>
{
await scrollView.ScrollToAsync(0, 0, false);
});
#else
// AVOID "MAGIC DELAYS" WHEN YOU CAN
await Task.Delay(1);
await scrollView.ScrollToAsync(0, 0, false);
#endif
}
}
一些建议。
首先,严格来说,ViewModel 中的 UI 依赖并不是 MVVM 方法。
Shell.Current.GoToAsync(...)
实际上属于代码隐藏,而不是VM。
其次,由于像Android这样的平台将会有一个系统“后退导航”按钮,所以你应该让它参与进来,让它做你想要它做的事情。
public partial class PageBView : ContentPage
{
public PageBView() => InitializeComponent();
private async void OnBackButtonClicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("///PageA");
}
protected override bool OnBackButtonPressed()
{
_ = Shell.Current.GoToAsync("///PageA");
return true;
}
}