繁体   English   中英

棱镜:首先使用多个ViewModels查看

[英]Prism: View First with multiple ViewModels

我在WPF项目中将Prism与Unity IOC容器一起使用。 对于所有其他视图,每个视图仅使用一个ViewModel。 因为此View应该是数据输入和输出的掩码,所以我想使用两个ViewModel。

对于当前到视图的导航,我使用以下代码:

_regionManager.RequestNavigate(RegionNames.ContentRegionName, typeof(Events).ToString());`

我的观点背后的代码:

public partial class Events : UserControl
{
    public Events(EventsViewModel viewModel)
    {
        InitializeComponent();
    }
}

ViewModel之一:

public class EventsViewModel : BindableBase
{
    public EventsViewModel()
    {
       // Some Code
    }
   // Some other Code
}

我听说过ViewModel Discovery,您在其中为View的构造函数提供了接口而不是实际的ViewModel。 但是我只能找到这么多信息。

// Example of such a Method
public Events(IViewModel viewModel)
{
    InitializeComponent();
    DataContext = viewModel
}

public Interface IViewModel
{

}

现在的问题是:如何导航到View并通过ViewModel告诉它应该作为DataContext获得? 我是编程的新手,MVVM-Pattern和英语不是我的母语,所以也许我错过了一些信息。 如果有人对此有一个答案,我将感到非常高兴。 提前致谢。

编辑:解决方法

我想出了一种对我有效的解决方法。 我使用了ViewModelLocationProvider的方法SetDefaultViewTypeToViewModelTypeResolver()并对其进行了自定义。

// Bootstrapper.cs
protected override void InitializeShell()
{
    var window = (MainWindow)this.Shell;
    Application.Current.MainWindow = window;

    // Calling the method
    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(ResolveViewModel);
    var regionManager = Container.Resolve<IRegionManager>();

    window._regionManager = regionManager;
    globalRegionManager = regionManager;

    regionManager.RegisterViewWithRegion(RegionNames.ContentRegionName, typeof(StartScreen));
    regionManager.RegisterViewWithRegion(RegionNames.ContentRegionName, typeof(Stock));

    window.Show();
}

// Property for handing over the desired ViewModel
public static Type DynamicViewModel { private get; set; }

private Type ResolveViewModel (Type viewType)
{
    string _viewModel = null;
    var name = viewType.FullName.Replace(".Views.", ".ViewModels.");

    if (DynamicViewModel != null)
        _viewModel = DynamicViewModel.ToString();
    else
        _viewModel = $"{name}ViewModel";

    var fullName = IntrospectionExtensions.GetTypeInfo(viewType).Assembly.FullName;
    var typeString = string.Format(CultureInfo.InvariantCulture, $"{_viewModel}, {fullName}");
    DynamicViewModel = null;

    return Type.GetType(typeString);
}

然后,当我要导航时,我会先移交给ViewModel。

private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
    Bootstrapper.DynamicViewModel = typeof(EventsViewModel);
    _regionManager.RequestNavigate(RegionNames.ContentRegionName, typeof(Events).ToString());
}

有点棘手,但似乎可以正常工作。

如果有更清洁的方法,我总是很乐意在这里进行。 :)

这里有一些获取视图的视图模型的技术(首先查看)。

构造函数背后的视图代码中的视图发现

public EventsView(EventsViewModel view_model)
{
    InitializeComponent();
    DataContext = view_model;
}

在构造函数后面的代码中显式更新视图模型

public EventsView()
{
    InitializeComponent();
    DataContext = new EventsViewModel();
}

XAML中用于视图的视图模型定位器

<UserControl x:Class="EventsModule.Views.EventsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <TextBlock Text="{Binding EventName}"></TextBlock>
    </Grid>
</UserControl>

只要您使用以下任何一种方法向区域管理器注册视图,以上任何一种都将起作用。 然后像在问题中一样进行导航。

RegionManager.RegisterViewWithRegion(RegionNames.ContentRegionName, typeof(EventsView));
UnityContainer.RegisterType(typeof(object), typeof(EventsView), typeof(EventsView).FullName);
UnityContainer.RegisterTypeForNavigation<EventsView>(typeof(EventsView).FullName);

第一个将激活该区域中的视图,通常可以在模块Initialize方法中看到。 后两个用于注册视图以供以后导航。 最后一个需要Prism.Unity命名空间。

我不认为一个视图可以有一个以上的视图模型,因为视图对象上只有一个DataContext属性。 您可能必须扩展一个视图模型以包含所需的所有内容。 有人可能会来证明我对此有错。 我已经看到了一个视图模型与多个视图共享的地方,但是从来没有一个视图具有多个视图模型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM