关于打开窗口和后退按钮的WPF良好实践

时间:2016-03-12 16:26:38

标签: c# wpf mvvm

我是WPF MVVM C#的初学者。当用户安装我的应用程序时,他将遵循教程。因此,对于教程的每个“屏幕”,我创建了一个Window。 在每个屏幕上,我有一个后退按钮。

所以,我对打开新窗口并返回上一个窗口的良好做法感到困惑。做这个的最好方式是什么?目前,我正在做:

第一个窗口(下一步按钮) - ViewModel1

<Button Command="{Binding NextWindowCommand}" >


public void NextWindow(object parameter)
{
    var newWindow = new Window2();
    newWindow.Show();
    newWindow.DataContext = new ViewModel2();
    CloseWindow();
}

第二个窗口(后退按钮)ViewModel2

<Button Command="{Binding BackWindowCommand}" >

    public void Back(object parameter)
    {
        var backWindow = new Window1();
        backWindow.Show();
        backWindow.DataContext = new ViewModel1();
        CloseWindow();
    }

关闭窗口方法(我的ViewModelBase):

    public bool? CloseWindowFlag
    {
        get { return _CloseWindowFlag; }
        set
        {
            _CloseWindowFlag = value;
            RaisePropertyChanged("CloseWindowFlag");
        }
    }


public virtual void CloseWindow(bool? result = true)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
    {
        CloseWindowFlag = CloseWindowFlag == null 
            ? true 
            : !CloseWindowFlag;
    }));
}

3 个答案:

答案 0 :(得分:4)

如果要根据DataTemplates动态切换视图,请使用ViewModel

<Window>
   <Window.Resources>
      <DataTemplate DataType="{x:Type ViewModelA}">
         <localControls:ViewAUserControl/>
      </DataTemplate>
      <DataTemplate DataType="{x:Type ViewModelB}">
         <localControls:ViewBUserControl/>
      </DataTemplate>
   <Window.Resources>
  <ContentPresenter Content="{Binding CurrentView}"/>
</Window>

如果Window.DataContextViewModelA的实例,则会显示ViewAWindow.DataContextViewModelB的实例,然后是ViewB将会显示。

我见过的最好的例子是Rachel Lim制作的。 See the example.

我强烈建议您关注Prism框架。 This tutorial is very nice.

<强>更新

让我举个例子,看看你应该把DataTemplates

放在哪里
<Window x:Class="SimpleMVVMExample.ApplicationView"
        ...The code omitted for the brevity...
        Title="Simple MVVM Example with Navigation" Height="350" Width="525">
    <Window.Resources>
       <DataTemplate DataType="{x:Type ViewModelA}">
         <localControls:ViewAUserControl/>
      </DataTemplate>
      <DataTemplate DataType="{x:Type ViewModelB}">
         <localControls:ViewBUserControl/>
      </DataTemplate>
    </Window.Resources>

    <DockPanel>
        <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
            <ItemsControl ItemsSource="{Binding ListOfViewModels}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}"
                                Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"
                                Margin="2,5"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Border>

        <ContentControl Content="{Binding CurrentDataTemplateViewModel}" />
    </DockPanel>
</Window>

要查看完整的工作示例please, see Rachel Lim's page.

要下载示例please, click here.

答案 1 :(得分:1)

首先,了解教程中窗口内容的内容真是太好了,它只是文本还是控件要填充?像文本框,复选框和其他东西。 这样说,如果你想避免每次用户点击下一个或上一个按钮时创建新窗口我建议你创建一次窗口,然后创建一个集合列表将窗口添加到集合中然后使用可见性来隐藏窗口当用户按下一个或上一个按钮时。您可以使用集合索引导航集合中的窗口和选定的窗口属性以获取正确的窗口并将其设置为可见或将其置于前面。

答案 2 :(得分:1)

您项目的良好做法:

  1. 使用框架管理您的窗口(如Caliburn.Micro或MVVM Light),
  2. 使用DI创建视图模型,
  3. MVVM的好处之一是“后退”操作几乎是免费的。当用户离开一个窗口转到新窗口时,请记住堆栈上的旧视图模型。当他点击“返回”时 - 只需关闭当前窗口,从堆栈中弹出视图模型,然后显示它。