首页 > 解决方案 > 如何在核心项目和具有更改页面的 WPF 应用程序之间使用依赖注入?

问题描述

我正在使用框架和for构建一个WPF程序。我创建了两个项目,一个用于其他应用程序的核心项目和一个特定应用程序。MVVMNinjectDependancy Injection.Net Class Library.NetWPF

目前,我正在使用ApplicationViewModel带有Property CurrentPage. CurrentPage是一种Enum称为ApplicationPage包含我的应用程序中不同页面的类型。在我的 WPF 应用程序的 MainWindow 中有一个框架,它Content使用值bound转换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 ModelsPage's ConstructorConverterViewModelsInjectedApplicationViewModel

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

我的第一个想法是,是否有某种方法可以使CurrentPage Property实际 a 具体ViewModel并执行 aswitch以便ViewModelConvertera 转换ViewModel为 a Page

但是Type ofCurrentPage是一个问题,因为它必须设置为 之一,ViewModels因此不能取 a different 的值ViewModel,让您只能使用一个ViewModel Class

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

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

标签: c#.netwpfmvvmdependency-injection

解决方案


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

<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 TriggerContent 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


推荐阅读