棱镜:使用多个ViewModel查看第一个

时间:2016-07-23 13:24:02

标签: c# mvvm unity-container prism ioc-container

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

对于View的当前导航,我使用此代码:

export class MyPipe implements PipeTransform {    
    transform(value:any, arg1:any, arg2:any, arg3:any):any {
    }

我的观点背后的代码:

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

其中一个ViewModels:

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

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

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

我现在的问题是:如何导航到View并告诉它应该以DataContext的形式获取ViewModel?我对编程相对较新,MVVM-Pattern和英语不是我的母语,所以也许我错过了一些信息。如果有人能得到答案,我会很高兴的。提前谢谢。

编辑:解决方法

我想出了一个对我有用的解决方法。我使用// Example of such a Method public Events(IViewModel viewModel) { InitializeComponent(); DataContext = viewModel } public Interface IViewModel { } 中的方法SetDefaultViewTypeToViewModelTypeResolver()并对其进行了自定义。

ViewModelLocationProvider

然后,当我想要导航时,我事先交出了ViewModel。

// 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);
}

有点棘手,但似乎没有任何例外情况。

如果有一种更清洁的方式,我总是很高兴来到这里。 :)

1 个答案:

答案 0 :(得分:1)

以下是获取视图视图模型的一些技术(首先查看)。

在构造函数

后面的视图代码中查看发现
public EventsView(EventsViewModel view_model)
{
    InitializeComponent();
    DataContext = view_model;
}

在构造函数

后面的代码中明确地新建视图模型
public EventsView()
{
    InitializeComponent();
    DataContext = new EventsViewModel();
}
视图的XAML中的

View model locator

<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方法中看到。最后2个用于注册视图以供以后导航。最后一个需要Prism.Unity命名空间。

我不相信视图可以包含更多的一个视图模型,因为视图对象上只有一个DataContext属性。您可能需要扩展一个视图模型以包含您需要的所有内容。有人可能会出现并证明我错了。我已经看到了一个视图模型与多个视图共享的位置,但从来没有一个视图具有多个视图模型。