我有一个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事件。请帮我这样做。
答案 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打开它。
从ViewModel:
有时可以直接直接打开private void OnOpenPatientWindowCommandExecute()
{
var o = new PatientWindow();
o.ShowDialog();
}
为此,您必须将 PatientWtrolow 从 UserControl 更改为窗口。
遵循严格的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建议的内容。