如何在MVVM结构之后打开新窗口?

时间:2014-08-06 08:23:21

标签: c# wpf xaml mvvm

下面是我项目的查看代码。实际上,当单击“帮助”按钮时,它会打开新窗口。因为我无法访问Window对象,所以我不得不在View部分的后端代码中编写它,MVVM不喜欢它。有没有什么方法可以严格遵循MVVM并从我的代码的View-Model部分打开新窗口?如果有,怎么样?因为我需要在那里访问新窗口。

VehicleForm.xaml

<Window x:Class="Seris.VehicleForm"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="VehicalForm" Height="500" Width="650"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">


<WrapPanel Orientation="Vertical" Margin="10 " >

    <Label Content="Vehical No" HorizontalAlignment="Left"/>
    <TextBox Name="VehicalNo_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding VehicleNo_Focus, UpdateSourceTrigger=LostFocus}"  HorizontalAlignment="Left" />

    <Label Name="VehicleNoError_Label" Foreground="Red" Content="{Binding VehicleNo_Error, UpdateSourceTrigger=PropertyChanged}" Height="36" Width="186"/>

    <Label Content="Model" HorizontalAlignment="Left"/>
    <TextBox Name="Model_Text" Height="24" Width="80" TextWrapping="Wrap" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" />
    <Label x:Name="ModelError_Label" Foreground="Red" Content="{Binding Model_Error, UpdateSourceTrigger=PropertyChanged}" Height="36" Width="186"/>

    <Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
    <DatePicker Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="136"/>
    <Label Name="ManufacturingDateError_Label" Foreground="Red" Content="{Binding ManufacturingDate_Error, UpdateSourceTrigger=PropertyChanged}" Height="36" Width="136"/>

    <Label Content="IU No" HorizontalAlignment="Left"/>
    <TextBox Height="23" Width="80" Name="IUNO_Text" TextWrapping="Wrap" Text="{Binding IUNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"/>
        <Label Name="IUError_Label" Foreground="Red" Content="{Binding IU_Error, UpdateSourceTrigger=PropertyChanged}" Height="36" Width="186"/>

    <Label Content="Personnel" HorizontalAlignment="Left"/>
    <ComboBox x:Name="Personnel_Combo" SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding PersonnelName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Width="126"/>

    <Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>

    <Button Name="Save_Button" Command="{Binding SaveButton_Command}" Content="Save" Width="66"/>
    <Button Name="Replace_Button" CommandParameter="replace" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Command="{Binding ReplaceButton_Command}" Content="Replace" Width="66"/>
    <Button Name="Remove_Button" CommandParameter="replace" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Command="{Binding RemoveButton_Command}" Content="Remove" Width="66"/>


    <Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="41" Width="137"/>

    <ListView Name ="Grid" Height="294" Width="371" >
        <DataGrid Name="DG" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" GridLinesVisibility="None" IsReadOnly="True" AutoGenerateColumns="False" BorderThickness="0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}"/>
                <DataGridTextColumn Header="Model" Binding="{Binding Model}" />
                <DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
                <DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
                <DataGridTextColumn Header="Personnel" Binding="{Binding PersonnelNameSelected}" />
                <DataGridTextColumn Header="Unique No" Binding="{Binding UniqueNo}"/>
            </DataGrid.Columns>
        </DataGrid>
    </ListView>

    <TextBlock Name="Preview" Text="{Binding EditText, UpdateSourceTrigger=PropertyChanged}"/>

    <ProgressBar Name="Progressbar" Minimum="0" Maximum="100" Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}" Height="11"/>
    <TextBlock Text="{Binding ElementName=Progressbar, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center"/>

    <Button Name="Help" Visibility="{Binding HelpVisibility, UpdateSourceTrigger=PropertyChanged}" CommandParameter="help" Height="50" Width="50" Click="Help_Click" HorizontalAlignment="Right">
        <Image Height="45" Width="45" Source="../Images/help.jpg" HorizontalAlignment="Left"/>
    </Button>

</WrapPanel>

</Window>

VehicleForm.xaml.cs

using Seris.ViewModels;
using Seris.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Seris
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class VehicleForm : Window
{
    public VehicleForm()
    {
        this.DataContext = new VehicleMainViewModel();
        this.Show();
        InitializeComponent();
    }

    private void Help_Click(object sender, RoutedEventArgs e)
    {
        Help helpWindow = new Help();
        helpWindow.Show();
    }

}
}

1 个答案:

答案 0 :(得分:0)

我认为您应该问问自己为什么要使用MVVM以及您希望它为您做什么,以及它将要解决/避免的问题。不要因为你应该做的而做MVVM。

在这种情况下,我不认为使用代码隐藏是错误的。 MVVM的目的不是拥有最短的.xaml.cs文件。

目的是:

  • 视图逻辑(VM)的可测试性,无需涉及视图。
  • 关注点分离:视图定义用户界面,视图模型通过其绑定,转换器等定义用户界面和业务逻辑之间的中介.ViewModel不需要知道View,它们可以单独开发。

您是否因为在后面的代码中打开一个窗口而错过了这两个目的?

  • 可测试性:你应该测试什么?拨打&#34; Show()&#34;?
  • 关注点分离:我认为你可以更好地分离代码,而不是以任何方式知道新窗口的VM。如果新窗口应该将master datacontext的一些细节作为datacontext,则VM应将其作为属性提供。