如何在MVVM WPF中的Mainwindow中加载usercontrol?

时间:2017-01-16 08:11:51

标签: c# wpf mvvm

我有一个MainWindow.Xaml文件。一个用户控件PatientWindow.Xaml。如何在MVVM架构的主窗口中加载患者窗口?

MainWindow.Xaml

<Window x:Class="PatientAdminTool.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:vm="clr-namespace:PatientAdminTool.ViewModel"
         xmlns:v="clr-namespace:PatientAdminTool.View"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        ResizeMode="CanResizeWithGrip" 
        WindowStyle="None"  
        WindowState="Normal"  
        Title="PatientAdmin Tools"           
        Height="750"
        Width="1400"
        AllowsTransparency="True" MouseLeftButtonDown="OnMouseLeftButtonDown" BorderThickness="1"  BorderBrush="#555252"  >  
    <WindowChrome.WindowChrome>
        <WindowChrome 
        CaptionHeight="0"     
          />
    </WindowChrome.WindowChrome>
</Window>

PatientWindow.xaml

下面提到了用户控制窗口

<UserControl x:Class="PatientAdminTool.View.PatientWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:vm="clr-namespace:PatientAdminTool.ViewModel"
         xmlns:v="clr-namespace:PatientAdminTool.View"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" >

    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <DockPanel Grid.Row="0" LastChildFill="True" Height="40" Background="#646161" >
            <StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
                <TextBlock Margin=" 10,5,0,0" HorizontalAlignment="Center" Text="Patients" FontSize="16"  TextAlignment="Center" VerticalAlignment="Center" Foreground="#FFFFFF"/>
            </StackPanel>
            <StackPanel Margin="10,10,0,0" DockPanel.Dock="Right" Background="Transparent"  Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" Width="50" >
                <StackPanel Background="Transparent"  Orientation="Horizontal" HorizontalAlignment="Right">
                    <Button Focusable="False" ToolTip="Close" VerticalAlignment="Center" Background="#646161" BorderThickness="0" BorderBrush="Transparent" Padding="-4" Click="Button_Click" >
                        <Button.Content>
                            <Grid Width="45" Height="23">
                                <TextBlock Foreground="White"   Text="r" FontFamily="Marlett" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </Grid>
                        </Button.Content>
                        <Button.Template>
                            <ControlTemplate TargetType="Button">
                                <ContentPresenter Content="{TemplateBinding Content}"/>
                            </ControlTemplate>
                        </Button.Template>

                    </Button>
                </StackPanel>
            </StackPanel>
        </DockPanel>
    </Grid>
</UserControl>

所以我需要使用MVVM在主窗口上方加载患者窗口。在这里,我需要在相应的View Model中编写load事件。请帮我这样做。

3 个答案:

答案 0 :(得分:1)

只需在MainWindow添加ControlPresenter

<ContentPresenter Content="{Binding YouTypeHere}">
             <ContentPresenter.Resources>
                 <DataTemplate DataType="{x:Type fristViewModel1Type}">
                     <youControlForViewModel1 />
                 </DataTemplate>
                 <DataTemplate DataType="{x:Type secondViewModel2Type}">
                     <youControlForViewModel2 />
                 </DataTemplate>
            </ContentPresenter.Resources>
         </ContentPresenter>

您可以通过将不同的VM绑定到ContentPresenter来更改视图。

答案 1 :(得分:1)

所以你想用MVVM打开一个新的子窗口?我假设您将从MainWindowViewModel打开它。

解决方案1:没有严格的MVVM

从ViewModel:

有时可以直接直接打开
private void OnOpenPatientWindowCommandExecute()
{
    var o = new PatientWindow();
    o.ShowDialog(); 
}

为此,您必须将 PatientWtrolow UserControl 更改为窗口

解决方案2:严格的MVVM

遵循严格的MVVM 的解决方案稍微复杂一些。在我写的解决方案中,您必须使用服务,将其添加到 MainWindowViewModel ,并将视图中的控件绑定到命令在ViewModel中。此外,它的编写就像使用依赖注入,这就是为什么你看到在构造函数中注入的服务。您可以通过在构造函数中实例化服务来避免这种情况。

MainWindowViewModel.cs

using Prism.Wpf.Commands; // For easy commands
using PatientAdminTool.Services; // Where you put your new service

public class MainWindowViewModel
{
   private IShowDialogService _ShowDialogService;

   public MainWindowViewModel(IShowDialogService showDialogService)
   {
       _ShowDialogService = showDialogService;

       // Or do: _ShowDialogService = new ShowDialogService();
       // But that's not a good practice and won't let you test
       // this ViewModel properly.

       OpenPatientWindowCommand = new DelegateCommand(OnOpenPatientWindowCommandExecute);
   }

   public ICommand OpenPatientWindowCommand { get; private set; }

   private void OnOpenPatientWindowCommandExecute()
   {
       _ShowDialogService.ShowPatientWindow();
   }
}

服务\ IShowDialogService.cs

public interface IShowDialogService
{
    void ShowPatientWindow();

    void ShowOtherWindow();

    // ...
}

服务\ ShowDialogService.cs

public class ShowDialogService : IShowDialogService
{
    public void ShowPatientWindow()
    {
        var patientWindowViewModel = new PatientWindowViewModel();
        var patientWindow = new PatientWindow();

        patientWindow.DataContext = patientWindowViewModel;

        patientWindow.ShowDialog();
    }

    public void ShowOtherWindow()
    {
        // Other window ...
    }
}

最后,您在视图中建立连接:

MainWindow.xaml

<Window
    xmlns:vm="clr-namespace:PatientAdminTool.ViewModel">
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <Button Command="{Binding OpenPatientCommand}">Open Patient</Button>
    </Grid>
</Window>

尚未在Visual Studio中尝试过,但这就是想法。

答案 2 :(得分:1)

如果您只是在同一个窗口中显示,只需将您的视图放在那里,就像其他任何控件一样:

<Window x:Class="PatientAdminTool.MainWindow"
        xmlns:v="clr-namespace:PatientAdminTool.View"... >  
    <WindowChrome.WindowChrome>
        <WindowChrome 
        CaptionHeight="0"/>
    </WindowChrome.WindowChrome>
    <v:PatientWindow/>
</Window>

您的窗口是否有根ViewModel?如果是这样,您可以绑定到PatientViewModel:

<v:PatientWindow DataContext="{Binding PatientViewModel}"/>

如果没有,通常会在代码隐藏中将第一个DataContext设置为ViewModel,如下所示:

<v:PatientWindow Name="PatientWindowView"/>

public partial class Window
{
    public MainWindow()
    {
        InitializeComponent();
        PatientWindowView.DataContext = new PatientWindowViewModel();

    }
}

如果您想要显示多个视图,请使用Shakra已回复的ContentPresenter。

如果您想打开一个新窗口,请使用AlbertoCardonaLópez建议的内容。