这个问题没有很好的答案。但是让我通过一些概念告诉你。当然,没有刷新,这也是很多倍的原因。刷新可能有一天会添加到框架中,但现在它是有问题的。
考虑一个导航服务
在您的应用中导航的一个好方法是将这项工作卸载到 NavigationService 类。这是一个简单的类,具有(类似于)自定义 GotoAppHub() 和 GotoItemDetail(Item) 方法。
这些方法的目的不是因为导航难,而是因为导航可以集中。它可以检查和创建Frame;而不是将其错误地留在 App.xaml.cs 中。
如果您的视图模型想要导航到一个页面,它只需调用NavigationService.GotoItemDetail(item); 来完成它,并传递项目。这很聪明有几个原因,让我来告诉你。
这很聪明的第一个原因是您可能根本不想导航。在某些情况下,导航依赖于加载的数据或具有权限的用户。使用导航服务,您可以集中导航逻辑和验证操作所需的测试。
这很聪明的第二个原因是它允许您保留传递给导航请求的参数。请记住,Frame 不会序列化自定义的复杂类型。因此,在这种情况下传递item 是一种不好的做法。导航服务可以将此参数保存在某个地方,以便目标视图模型可以获取它。此外,它可以为您的 Refresh() 持久保存它。
考虑一个静态存储库类
当一个视图模型被加载时,它应该没有必要知道是什么先前的视图模型导致它被加载。相反,视图模型应该知道它应该做什么。为了完成工作,它需要数据。每个视图模型都可以使用存储库类来请求“当前”记录。当前记录将在导航发生时由导航服务设置。此外,存储库类知道当没有当前记录时该做什么,并在需要时获取它。
除了持有对当前记录的引用之外,存储库类还理解持久性。我的意思是,当应用程序加载时,它知道如何填写列表。当应用程序暂停时,它知道如何将数据保存到文件或网络服务,或任何你使用的东西。因此,视图模型不知道这一点,因此更简单、更易于维护。
考虑 Reload() 方法
在导航服务中你需要 reload 方法。更重要的是,只有在导航服务中 reload 方法才能最有效,因为导航服务知道当前的type 和当前的参数值。导航服务可以将这些值存储在本地字段中,并且 reload 方法可以简单地重复导航。
但是,请记住后面的堆栈。这就像浏览器的导航,重复导航意味着同一个页面将存在两次,并且导航服务中的 GoBack() 方法在您返回两次之前不会返回。解决方法很简单,记得用Services.NavigationService.Instance.Frame.BackStack.Remove()删除即可。
记住加载成本
有时,当页面加载时,加载 UI 会产生相当大的成本。这是因为无论你在做什么都不是微不足道的。调用 Reload() 将导致页面的加载重复。这是您根本无法克服的成本。但是,可能存在应该绕过的页面加载依赖项。例如,您可能会在页面加载时启动 Web 服务操作 - 并且不应重复该操作。这取决于您是否保留指示页面已加载的静态布尔值。但重要的是你不要忘记它。
存储库的另一个好处
我在上面的几段中提到,您的导航服务可以记住最后传递的参数以使 reload 方法起作用。如果您有一个内部规则,即只有导航服务可以写入并发类,那么您的导航服务实际上不必记住。它只需要记住最后导航到的类型。这是因为并发类已经具有对传入项目的引用。然而,这并不总是有用的。有时会调用 reload 来丢弃当前的更改,这意味着需要重新加载当前项或必须刷新当前更改。这一切都必须是定制的,但如果我至少不提及它,我会感到难过。
结论
这仅应被视为建议。话虽如此,我已经在这里描述了市场上大部分成功的大型 WPF 和 Windows 应用程序。使用 MVVP 模式、用于导航的服务模式、用于并发的存储库模式——这一切都得到了很好的证明。但你是开发者。最后,您应该选择最好的。
如果你不喜欢这些,你可以这样做:
public bool Reload()
{
if (!this.Frame.BackStack.Any())
return false;
var current = this.Frame.BackStack.First();
this.Frame.BackStack.Remove(current);
return this.Frame.Navigate(current.SourcePageType, current.Parameter);
}
祝你好运!