2016-01-07 47 views
4

我正在写一个小应用程序,同时在WPF中学习MVVM。创建一个没有MVVM框架的子窗口

只要我继续使用一个窗口,一切都很简单。 现在我想用特定的ViewModel打开一个新窗口。

我有一个主ViewModel,其中包含一个命令,应该打开一个新的Window/ViewModel,以及一个参数。

my main window

要在MVVM的方式做到这一点,我创建了一个的NavigationService,我想这样的调用其中:

public MainWindowViewModel() 
    { 
     DetailsCommand = new DelegateCommand(Details); 
    } 

    public void Details() 
    { 
     SessionsViewModel sessions = new SessionsViewModel(); 
     _NavigationService.CreateWindow(sessions); 
    } 

我注意到,这是可能的“绑定”视图和的ViewModels在XAML,像这样:

<Application x:Class="TimeTracker.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="clr-namespace:TimeTracker" 
      xmlns:vm="clr-namespace:TimeTracker.ViewModels" 
      xmlns:vw="clr-namespace:TimeTracker.Views" 
      StartupUri="Views/MainWindow.xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <DataTemplate DataType="{x:Type vm:MainWindowViewModel}"> 
       <vw:MainWindow /> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type vm:SessionsViewModel}"> 
       <vw:Sessions /> 
      </DataTemplate> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

<Window x:Class="TimeTracker.Views.Sessions" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:TimeTracker.Views" 
     xmlns:vm="clr-namespace:TimeTracker.ViewModels" 
     mc:Ignorable="d" 
     Title="Sessions" Height="300" Width="300"> 
    <Window.DataContext> 
     <vm:SessionsViewModel/> 
    </Window.DataContext> 
    <Grid> 
     <TextBlock Text="Hallo" /> 
    </Grid> 
</Window> 

我遇到的问题是,我不知道我怎么可以在我的NavigationService使用此ResourceDictionary中,所以我可以通过仅使用ViewModel创建一个新窗口。

class NavigationService 
{ 
    public void CreateWindow(IViewModel viewModel) 
    { 
     //How do I create a new Window using the ResourceDictionary? 
    } 
} 
+2

http://stackoverflow.com/a/25846192/4560635 – Jeremy

回答

1

确保您的新窗口中有ContentControl或ContentPresenter,以便可以呈现ViewModel。接下来,确保资源字典在范围内。将它放在Application.Resources中将使其成为全局的,并保证WPF可以找到DataTemplate。

另外,不要在DataTemplate中使用Window类作为视图。使用你的子窗口面板(例如,Grid,StackPanel等)。

我这样做:

<blah:MyChildWindow> 
    <ContentControl Content={Binding DataContext}/> 
</blah:MyChildWindow> 

And in Application.Resources: 

<DataTemplate DataType={x:Type blah:MyViewModel}> 
    <blah:MyChildWindow/> 
</DataTemplate> 

BTW - 使用的DataTemplates你正在尝试做的方式是一个很好的模式。

+0

感谢您的回答。我更新了我的XAML绑定以显示它是全局的。你能解释为什么你的'MyChildWindow'只有一个ContentControl吗?我试图在视图中放置一些内容,如网格或列表。请参阅我的更新视图。 –

+0

使用您正在使用的模式,视图内容由DataTemplate本身(或您在其中引用的UserControl /自定义控件)提供。我建议ContentControl,因为它将DataTemplate WPF可以找到的任何内容应用于其内容ViewModel。如果您有一个项目列表而不是单个项目,那么您可以使用像ListBox这样的ItemsControl - 它也会应用它为列表中的每个项目找到的任何DataTemplate。 – hoodaticus

相关问题