c# - 使用自定义导航服务,如何将参数传递给下一个视图模型?
问题描述
我正在加快 Xamarin 的速度。我正在使用“掌握 Xamarin.Forms:使用 Xamarin.Forms 4,第 3 版构建多平台、本机移动应用程序的应用程序架构技术”作为指南。这让我创建了一个自定义导航服务。
这是实现(为简洁起见,我跳过了界面)
namespace wfw_dispenser.Services
{
public class XamarinFormsNavService : INavService
{
readonly IDictionary<Type, Type> _map = new Dictionary<Type, Type>();
public event PropertyChangedEventHandler CanGoBackChanged;
public INavigation XamarinFormsNav { get; set; }
public bool CanGoBack => XamarinFormsNav.NavigationStack?.Any() == true;
public async Task GoBack()
{
if (CanGoBack)
{
await XamarinFormsNav.PopAsync(true);
OnCanGoBackChanged();
}
}
public async Task NavigateTo<TVM>()
where TVM : BaseViewModel
{
await NavigateToView(typeof(TVM));
if (XamarinFormsNav.NavigationStack.Last().BindingContext is BaseViewModel)
{
((BaseViewModel)XamarinFormsNav.NavigationStack.Last().BindingContext).Init();
}
}
public async Task NavigateTo<TVM, TParameter>(TParameter parameter)
where TVM : BaseViewModel
{
await NavigateToView(typeof(TVM));
if (XamarinFormsNav.NavigationStack.Last().BindingContext is BaseViewModel<TParameter>)
{
((BaseViewModel<TParameter>)XamarinFormsNav.NavigationStack.Last().BindingContext).Init(parameter);
}
}
public void RemoveLastView()
{
if (XamarinFormsNav.NavigationStack.Count< 2)
{
return;
}
var lastView = XamarinFormsNav.NavigationStack[XamarinFormsNav.NavigationStack.Count - 2];
XamarinFormsNav.RemovePage(lastView);
}
public void ClearBackStack()
{
if (XamarinFormsNav.NavigationStack.Count < 2)
{
return;
}
for (var i = 0; i < XamarinFormsNav.NavigationStack.Count - 1; i++)
{
XamarinFormsNav.RemovePage(XamarinFormsNav.NavigationStack[i]);
}
}
public void NavigateToUri(Uri uri)
{
if (uri == null)
{
throw new ArgumentException("Invalid URI");
}
Device.OpenUri(uri);
}
async Task NavigateToView(Type viewModelType)
{
if (!_map.TryGetValue(viewModelType, out Type viewType))
{
throw new ArgumentException("No view found in view mapping for " + viewModelType.FullName + ".");
}
// Use reflection to get the View's constructor and create an instance of the View
var constructor = viewType.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(dc => !dc.GetParameters().Any());
var view = constructor.Invoke(null) as Page;
var vm = ((App)Application.Current).Kernel.GetService(viewModelType);
view.BindingContext = vm;
await XamarinFormsNav.PushAsync(view, true);
}
public void RegisterViewMapping(Type viewModel, Type view)
{
_map.Add(viewModel, view);
}
void OnCanGoBackChanged() => CanGoBackChanged?.Invoke(this, new PropertyChangedEventArgs("CanGoBack"));
}
}
在我看来,有一个 NavigateTo 需要一个参数。我试过了,它在日志中没有任何错误。文本中没有关于此方法的任何内容来解释如何使用它。
为此,我可能必须在“捕捉”视图模型中做一些事情。有人可以帮我吗?
解决方案
首先,您必须从 BaseViewModel 的参数化版本进行扩展。在您的情况下,由于您正在传递 a PaymentRequest
,因此这将是:
public class CheckoutViewModel : BaseViewModel<PaymentRequest>
然后BaseViewModel<T>
有一个Init
可以实现的虚拟方法
public class BaseViewModel<TParameter> : BaseViewModel
{
protected BaseViewModel(INavService navService, IAnalyticsService analyticsService)
: base(navService, analyticsService)
{
}
public override void Init()
{
Init(default(TParameter));
}
public virtual void Init(TParameter parameter)
{
}
}
推荐阅读
- wordpress - 在 Wordpress 中自动重定向/重写 1000 个旧帖子 url
- facebook - Facebook 新权限 - 无法将视频发布到用户时间轴
- python - 如何在 txt 文件中搜索一个单词,然后打印包含该单词的行(Python)?
- python - 如何使用 Mysql Python 连接器检索二进制数据?
- excel - 使用 VLOOKUP 时需要创建重复行
- android - Xamarin Forms - Android - 更改每个内容页面的向上/后退箭头颜色
- asp.net - 在 Azure 上运行的 ASP.NET 应用程序未删除 Redis 客户端
- c# - 从 MVC 操作返回 html 内容时引用链接的 css 和 js 资源
- kubernetes - 如何确保 kubernetes cronjob 在失败时不会重新启动
- python-2.7 - 如何将数据集与 mxnet 结合起来?