用于 WPF 导航的窗口、页面和用户控件?

Posted

技术标签:

【中文标题】用于 WPF 导航的窗口、页面和用户控件?【英文标题】:Window vs Page vs UserControl for WPF navigation? 【发布时间】:2012-08-25 17:27:00 【问题描述】:

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

我的选择似乎是

窗口 页面 用户控件

但我不明白它们之间的区别是什么,以及何时应该使用它们。

谁能为我解释一下这些差异,并举例说明您可以将每种情况/应用程序用于哪些情况/应用程序?

【问题讨论】:

【参考方案1】:

Window 对象就是它听起来的样子:它为您的应用程序提供了一个新的Window。当你想弹出一个全新的窗口时,你应该使用它。我不经常在 WPF 中使用多个 Window,因为我更喜欢将动态内容放在我的主窗口中,这些内容会根据用户操作而变化。

页面是您窗口内的页面。它主要用于基于 Web 的系统,例如 XBAP,在其中您有一个浏览器窗口,并且可以在该窗口中托管不同的页面。也可以在Navigation Applications 中使用,如sellmeadog said。

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

在窗口之间导航时,您可以简单地创建一个新的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 设计模式。我有一个非常 basic example on my blog,它说明了如何使用 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>

【讨论】:

我有一个问题,据我所知,MVVM 似乎可以很好地处理数据集,但是静态表单(例如审计的输入表单)呢?我应该为静态页面使用页面还是用户控件? @Herrozerro 如果我想使用 MVVM 制作审核表单,我将有一个 AuditViewModel 包含表单的所有数据和功能,我会使用 @987654341 来绘制它@UserControl,或者只是一个DataTemplate 谢谢!实际上在浏览了您的博客和其他一些网站之后,我对 MVVM 的工作原理有了更好的了解。 @Herrozerro ViewModel 通常是为View 构建的,而Models 是您的应用程序使用的数据对象和类(“构建块”)(ViewModels @GTS13 是的,我经常这样做。我将TabControl.ItemsSource 绑定到对象集合,并使用DataTemplates 告诉WPF 如何在每个选项卡上绘制每种对象类型。通常类似于this【参考方案2】: 窗口就像Windows.Forms.Form,所以只是一个新窗口

页面是,根据online documentation:

封装可以导航到的内容页面 并由 Windows Internet Explorer、NavigationWindow 和 Frame 托管。

所以如果你想可视化一些 html 内容,你基本上会使用它

UserControl 适用于您想要创建一些可重用组件(但不是独立组件)以在多个不同的Windows

中使用它的情况

【讨论】:

感谢您的回答。例如,如果您正在构建一个左侧有按钮的应用程序,但您想在右侧查看这些按钮内的内容,您会使用用户控件吗? @Steve: 使用UserControl 以防您认为您将在此窗口上使用的同一组控件也将在其他窗口上使用,因此不要编写双重代码,只需创建一个UserControl,但如果没有,只需将用于可视化数据的控件放在 Window 本身上,在您指定的按钮的右侧。 我认为应该再添加一项:DataTemplates。当您想告诉 WPF 如何在特定范围内绘制项目时使用这些。例如,如果您想将Buttons 绘制成圆形,您可以简单地使用DataTemplate 而不是UserControl。当我想要一个具有自己功能的新控件时,或者当我为单个组件(例如View)提供大量 XAML 时,我通常使用UserControls。对于不需要任何特殊功能的较小 XAML 位,您应该使用 DataTemplate 而不是创建 UserControl 一般来说,Page 的内容不是 HTML,而是 XAML。但是,Page 绑定到导航框架,在概念上类似于在 Web 浏览器中完成导航的方式。 (如果应用程序是 XBAP 应用程序,页面甚至可以托管在浏览器中。)【参考方案3】:

一切都取决于您要构建的应用程序。如果您正在构建基于对话框的应用程序,请使用 Windows。如果您正在构建navigation based app,请使用Pages。 UserControls 将非常有用,无论您走哪条路,您都可以在 Windows 和 Pages 中使用它们。

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

【讨论】:

【参考方案4】:

我们通常将 One Main 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");
        
    

这是一种方法我们也可以使用选项卡控件而不是 Fram 并使用字典向其中添加页面,同时添加新页面检查控件是否已存在然后仅导航,否则添加和导航。我希望这会对某人有所帮助

【讨论】:

【参考方案5】:

大部分都发布了正确答案。我想添加一些链接,以便您参考它们并对此有清晰和更好的想法:

用户控制: http://msdn.microsoft.com/en-IN/library/a6h7e207(v=vs.71).aspx

关于WPF的page和window的区别: Page vs Window in WPF?

【讨论】:

以上是关于用于 WPF 导航的窗口、页面和用户控件?的主要内容,如果未能解决你的问题,请参考以下文章

在默认 AppDomain 中的 Winforms 中托管 WPF 用户控件的弹出窗口中的选项卡导航损坏

从用户控件中导航WPF选项卡控件?

WPF用户控件嵌套控件-从用户控件切换用户控件

如何使用 WPF 用户控件关闭父窗口

WPF 将对象从窗口的用户控件传递到另一个窗口的用户控件

在 WPF Frame 控件中关闭导航页面声音