在 Prism 中添加另一个 ViewModelLocator 约定(不覆盖)

Add another ViewModelLocator convention in Prism (not override)

项目 (WPF) 有这些文件夹:

如何让 Prism 的 ViewModelLocator 与它们一起工作(Views> ViewModels & SubViews> SubViewModels),我发现的解决方案只适用于一种约定:

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
    {
        var viewName = viewType.FullName.Replace(".ViewModels.", ".CustomNamespace.");
        var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
        var viewModelName = $"{viewName}ViewModel, {viewAssemblyName}";
        return Type.GetType(viewModelName);
    });
}

您可以选择配对注册(没有听起来那么糟糕,因为无论如何您都必须注册导航)。

或者,您可以一个接一个地实现这两个约定 - 获取视图的名称,减去“Views”并添加“ViewModels”,然后尝试获取视图模型的类型。如果失败,请减去“SubViews”并添加“SubViewModels”,然后重试。您甚至可以检查交叉组合(例如“SubViews.ViewA”和“ViewModels.ViewAViewModel”)...

我通过检查 viewType 解决了它,并基于它,我 return 适当的 ViewModel 类型:

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
    {
        string prefix;
        if (viewType.FullName.Contains(".SubViews."))
        {
            prefix = viewType.FullName.Replace(".SubViews.", ".SubViewModels.");
        }
        else
        {
            prefix = viewType.FullName.Replace(".Views.", ".ViewModels.");
        }
        var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
        var viewModelName = $"{prefix}ViewModel, {viewAssemblyName}";
        return Type.GetType(viewModelName);
    });
}