用于WPF导航的窗口,页面还是用户控件?


192

我目前正在编写一个桌面应用程序,但是当我将某人重定向到应用程序的新部分时,似乎无法理解该使用什么。

我的选择似乎是

  • 窗口
  • 用户控件

但我不了解它们之间的区别以及何时应使用它们。

有人可以为我解释这些差异,并举例说明您可能在每种情况/应用中使用哪种情况/应用吗?

Answers:


337

一个窗口对象正是这听起来像:它是一个新Window的应用程序。当您要弹出一个全新的窗口时,应该使用它。Window在WPF中,我通常不会使用多个内容,因为我更喜欢将动态内容放入基于用户操作而变化的主窗口中。

一个网页是你的窗口内的页面。它主要用于XBAP之类的基于Web的系统,在该系统中,您只有一个浏览器窗口,并且可以在该窗口中托管不同的页面。它也可以在导航应用程序中使用,例如sellmeadog说

一个用户控件是一个可重用的用户创建的控件,您可以添加到您的用户界面,你会添加任何其他控制方式相同。通常,UserControl当我要构建一些自定义功能时(例如CalendarControl),或者当我有大量相关的XAML代码时(例如View在使用MVVM设计模式时),我会创建一个。

在窗口之间导航时,您可以简单地创建一个新Window对象并显示它

var NewWindow = new MyWindow();
newWindow.Show();

但是就像我在回答开头所说的那样,我尽可能不管理多个窗口。

我偏爱的导航方法是使用创建一个动态内容区域ContentControl,并在其中填充一个UserControl包含当前视图的内容。

<Window x:Class="MyNamespace.MainWindow" ...>
    <DockPanel>
        <ContentControl x:Name="ContentArea" />
    </DockPanel>
</Window>

在您的导航事件中,您只需使用

ContentArea.Content = new MyUserControl();

但是,如果您使用的是WPF,我强烈建议您使用MVVM设计模式。我的博客上有一个非常基本的示例,说明了如何使用以下模式使用MVVM进行导航:

<Window x:Class="SimpleMVVMExample.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleMVVMExample"
        Title="Simple MVVM Example" Height="350" Width="525">

   <Window.Resources>
      <DataTemplate DataType="{x:Type local:HomeViewModel}">
         <local:HomeView /> <!-- This is a UserControl -->
      </DataTemplate>
      <DataTemplate DataType="{x:Type local:ProductsViewModel}">
         <local:ProductsView /> <!-- This is a UserControl -->
      </DataTemplate>
   </Window.Resources>

   <DockPanel>
      <!-- Navigation Buttons -->
      <Border DockPanel.Dock="Left" BorderBrush="Black"
                                    BorderThickness="0,0,1,0">
         <ItemsControl ItemsSource="{Binding PageViewModels}">
            <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>

      <!-- Content Area -->
      <ContentControl Content="{Binding CurrentPageViewModel}" />
   </DockPanel>
</Window>

屏幕截图1 屏幕截图2


我有一个问题,我可以说MVVM似乎可以很好地与数据集一起使用,但是静态表单(例如审核的输入表单)呢?我应该对静态页面使用页面还是用户控件?
Herrozerro

2
@Herrozerro如果我想使用MVVM制作审核表,我将拥有一个AuditViewModel包含该表的所有数据和功能的文件,我将使用AuditViewUserControl或仅由DataTemplate
Rachel

1
谢谢!实际上,在浏览了您的博客和其他一些站点之后,我对MVVM的工作方式有了更好的了解。
Herrozerro 2013年

1
@Herrozerro ViewModel通常为构建View,而则Models是应用程序(ViewModels)使用的数据对象和类(“构建模块” )
Rachel

1
@ GTS13是的,我经常这样做。我将绑定TabControl.ItemsSource到对象集合,并使用DataTemplates告诉WPF如何在每个选项卡上绘制每种对象类型。通常像这样
雷切尔

13
  • 窗口就像Windows.Forms.Form,所以只是一个新窗口
  • 根据在线文档页面是:

    封装可以浏览到Windows Internet Explorer,NavigationWindow和Frame并由其托管的内容页面。

    因此,如果您要可视化一些HTML内容,则基本上可以使用它

  • UserControl适用于要创建一些可重用组件(而不是独立组件)以在多个不同组件中使用它的情况Windows


谢谢您的回答。因此,例如,如果您要构建一个左侧具有按钮的应用程序,但又想在右侧看到这些按钮中的内容,则可以使用用户控件?
史蒂夫

@Steve:UserControl如果您认为要在该窗口上使用的同一组控件也将在其他窗口上使用,则可以使用,因此,无需编写双重代码,只需创建一个UserControl,否则,只需放置用于可视化控件的控件即可。您Window所指按钮右侧的数据本身。
提格伦2012年

6
我认为应该再增加一项:DataTemplates。当您想告诉WPF如何在特定范围内绘制项目时,可以使用它们。例如,如果您想将自己绘制Buttons为圆形,则可以简单地使用a DataTemplate而不是a UserControlUserControls当我想要一个具有其自身功能的新控件时,或者当我对单个组件有很多XAML(例如用于)时,通常会用到View。对于不需要任何特殊功能的较小XAML,您应该使用a DataTemplate而不是创建UserControl
Rachel

3
通常,a的内容Page不是HTML,而是XAML。但是,将a Page绑定到导航框架中,该框架在概念上类似于在Web浏览器中完成导航的方式。(如果应用程序是XBAP应用程序,则页面甚至可以托管在浏览器中。)
Martin Liversage,2012年

6

一切都取决于您要构建的应用程序。使用Window■如果你正在构建一个基于对话框的应用程序。使用Page■如果你正在构建一个基于导航应用UserControls不管沿什么方向前进,都将很有用,因为您可以在Windows和Pages中使用它们。

一个开始探索的好地方是这里:http : //windowsclient.net/learn


5

我们通常将One Main Window用于应用程序,而在需要弹出窗口的情况下也可以使用其他窗口,因为可以使用在设计时可见的Window来代替XAML中不可见的弹出控件,跟...共事

另一方面,我们使用许多页面从一个屏幕导航到另一个屏幕,例如用户管理屏幕到“订单屏幕”等。在主窗口中,我们可以使用Frame控件进行导航,例如XAML下方

    <Frame Name="mainWinFrame" NavigationUIVisibility="Hidden"  ButtonBase.Click="mainWinFrame_Click">
    </Frame>

C#

     private void mainWinFrame_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (e.OriginalSource is Button)
            {
                Button btn = (Button)e.OriginalSource;

                if ((btn.CommandParameter != null) && (btn.CommandParameter.Equals("Order")))
                {

                    mainWinFrame.Navigate(OrderPage);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error");
        }
    }

那是做到这一点的一种方法。我们还可以使用Tab控件代替Fram,并在添加新页面时使用Dictionary添加页面到它,检查控件是否已经存在,然后仅进行导航和添加导航。我希望能对某人有所帮助


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.