我正在使用WPF框架和Ninject for Dependancy Injection一起构建一个Dependancy Injection程序。我创建了两个项目,一个用于其他.Net应用程序的.Net核心项目和一个特定于WPF的应用程序。
目前,我正在使用带有ApplicationViewModel和Property CurrentPage的应用程序更改页面。CurrentPage是一个名为ApplicationPage的Enum类型,它包含应用程序中的不同页面。在我的WPF应用程序的MainWindow中有一个框架,它的Content是bound到CurrentPage Property,并使用一个值转换器将值转换成使用switch语句创建的不同的CustomPages,如下所示:
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传递到Converter中的Page's Constructor中,使用的是ViewModels,这反过来又进入了ApplicationViewModel类,类似于这样:
case ApplicationPage.PageOne:
return new PageOne(PageOneViewModel);我的第一个想法是,是否有办法使CurrentPage Property实际上是一个特定的ViewModel,并执行一个ViewModel在其上执行的switch,以便Converter将ViewModel转换为Page?
但是,类型 of CurrentPage是一个问题,因为它必须设置为一个ViewModels之一,因此不能使用其他ViewModel的值,因此只能使用一个ViewModel Class来处理。
我的想法是:有办法把ViewModel传递给Converter吗?或者我可以将CurrentPage设置为IViewModelFactory并在工厂的转换器中创建ViewModel吗?在这种情况下,如何更改CurrentPage的值以更改应用程序中的页面?
在遵循这种逻辑的同时,是否有一种方法可以坚持使用Dependency Injection,或者还有其他方法,我是否需要重新考虑页面更改的代码?不幸的是,我看到的大多数例子都落入了所谓的ServiceLocator反模式。
发布于 2018-06-08 09:32:01
答案是使用数据模板,如下所示
<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 of PageNames。
https://stackoverflow.com/questions/50594407
复制相似问题