如何在更改页面的Core项目和WPF应用程序之间使用依赖注入?

时间:2018-05-29 23:35:47

标签: c# .net wpf mvvm dependency-injection

我正在使用WPF框架制作MVVM计划,并为Ninject制作Dependancy Injection。我创建了两个项目,一个.Net Class Library核心项目,用于其他.Net应用程序和WPF特定应用程序。

目前,我正在使用ApplicationViewModel Property CurrentPage使用我的应用更改网页。 CurrentPage是名为Enum的{​​{1}}类型,其中包含我的应用程序中的不同页面。在我的WPF应用程序的MainWindow中,ApplicationPage Contentbound的框架使用值转换器将值转换为我使用的CurrentPage Property CustomPages声明,如下:

switch

我想使用if (value is ApplicationPage) switch ((ApplicationPage)value) { case ApplicationPage.PageOne: return new PageOne(); case ApplicationPage.PageTwo: return new PageTwo(); default: throw Exception; } } Constructor将这些网页的Injection传递到View Models中的Page's Constructor,使用Converter ViewModels已成为InjectedApplicationViewModel,有点像这样:

case ApplicationPage.PageOne:
    return new PageOne(PageOneViewModel);

我的第一个想法是,是否有某种方法可以使CurrentPage Property实际上成为特定ViewModel并执行switch ViewModel所以ConverterViewModel转换为Page

然而CurrentPage类型是一个问题,因为它必须设置为ViewModels之一,因此无法获取其他ViewModel的值},让您只使用一个ViewModel Class来处理。

我的想法是:有没有办法将ViewModel传递给Converter?或者我可以将CurrentPage设置为IViewModelFactory并在工厂内的转换器中创建ViewModel吗?在这种情况下,如何更改CurrentPage的值以更改应用程序中的页面?

是否有办法在遵循此逻辑时坚持Dependency Injection,或者是否有另一种方式我是否需要重新考虑我的代码以进行页面更改?不幸的是,我见过的大多数例子都属于所谓的ServiceLocator反模式。

1 个答案:

答案 0 :(得分:0)

答案是使用如下数据模板,

<Window.Resources>
    <DataTemplate x:Key="View1Template" DataType="{x:Type local:MainWindowViewModel}">
        <!-- Custom control style with a Data Context set to a Viewmodel 
        object in the MainWindowViewModel -->
        <local:CustomPage1 DataContext="{Binding CustomPage1ViewModel}" />
    </DataTemplate>

    <DataTemplate x:Key="View2Template" DataType="{x:Type local:MainWindowViewModel}">
        <!-- Custom control style with a Data Context set to a Viewmodel 
        object in the MainWindowViewModel -->
        <local:CustomPage2 DataContext="{Binding CustomPage2ViewModel}" />
    </DataTemplate>
</Window.Resources>

然后在Data Trigger;

中设置Content Control Style
<ContentControl Content="{Binding}">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">

            <!-- The Default/initial View being shown -->
            <Setter Property="ContentTemplate" Value="{StaticResource View1Template}" />

            <!-- Triggers bound to the CurrentView Property -->
            <Style.Triggers>
                <DataTrigger Binding="{Binding CurrentView}" Value="1">
                    <Setter Property="ContentTemplate" Value="{StaticResource View1Template}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding CurrentView}" Value="2">
                    <Setter Property="ContentTemplate" Value="{StaticResource View2Template}" />
                </DataTrigger>
            </Style.Triggers>

        </Style>
    </ContentControl.Style>
</ContentControl>

CurrentView是一个属性,可以在代码中更改为Trigger UI中的更改 - 可以设置为Enum PageNames