【问题标题】:Change between pages in WPF在 WPF 中的页面之间更改
【发布时间】:2014-07-24 11:49:06
【问题描述】:

我想制作一个与任何网站一样的布局——页眉、侧边栏和页脚保持不变,但中心部分。我有多个页面/窗口要在 wpf blend C# 应用程序中显示,它们完全不同。例如,stackoverflow 的主页有一个布局,每个问题都有另一个布局。这是另一个例子:

我必须在以前的项目中这样做,并且我使用了一个网格布局,然后,对于每个页面,我必须将它们全部隐藏()并将它们显示在顶部 -

有什么诀窍?如何在 wpf 应用程序中做同样的事情?在一个典型的 C# 应用程序中,我每次都必须打开一个子窗口,但现在这看起来很难看。

提前谢谢你!

【问题讨论】:

  • 您可以创建一个主窗口并托管用户控件,具体取决于您的要求。
  • 另外,您还有另一个选择,我可以用来做类似的事情。在您的 MainWindow 中创建您想要的布局。在您想要更改的任何地方保持框架控制。并根据用户操作显示页面。

标签: c# wpf blend


【解决方案1】:

如果你打算在 WPF 中使用Pages,那么你需要阅读 MSDN 上的Navigation Overview 页面。然而,简而言之,您可以使用 NavigationService Class 在 WPF 应用程序中的 Pages 之间导航。要从后面的代码更改页面,您可以执行以下操作:

NextPage page = new NextPage();
NavigationService.Navigate(page);

要让用户更改Page,您可以使用Hyperlink Class 您的Pages:

<Hyperlink NavigateUri="pack://application:,,,/AppName;component/Pages/NextPage.xaml">
    Navigate to Next Page
</Hyperlink>

要获得所需的页面设置,您必须将Pages 加载到Frame 中,然后您可以在MainWindow.xaml 中任意布局:

<Frame Source="pack://application:,,,/AppName;component/Pages/SomePage.xaml" />

【讨论】:

  • .NET Framework 4.5 的 Navigation Overview MSDN 页面似乎已被删除/损坏,但您仍然可以找到 .NET Framework 4.0 version here
  • 非常感谢@Merlin2001...我现在更新了链接。
【解决方案2】:

听起来您需要一个自定义用户控件和一些数据绑定。

您可以将 XAML 中的 DataTemplates 声明为资源,并以模型类型为键,以便 WPF 自动选择正确的 DataTemplate:

  • 有一个主 ViewModel,它公开了一个 ImageSourceViewModel 属性。此属性将根据需要返回 CameraSourceViewModel 或 FileSourceViewModel。

  • 在您的页面中,DataContext 将是主要的 ViewModel,您将拥有这样的 XAML:

那么,

<Page x:Class="Page1"
  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:my="clr-namespace:WpfApplication1"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="300"
  Title="Page1">
<Page.Resources>
    <DataTemplate DataType="{x:Type my:CameraSourceViewModel}">
        <my:CameraSourceView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type my:FileSourceViewModel}">
        <my:FileSourceView/>
    </DataTemplate>
</Page.Resources>
<Grid>
    <ContentControl Content="{Binding ImageSourceViewModel}"/>
</Grid>

我应该指出,这个例子使用了 MVVM 模式来允许 viewmodel 层决定中间的内容。希望这已经足够清楚了,如果没有,请给我留言,我会尝试扩展它!

【讨论】:

    【解决方案3】:

    假设我有一个主视图模型,我在其中创建了一个 CurrentPage 属性,该属性将告诉您要显示哪个页面。

    /// <summary>
    /// Returns the page ViewModel that the user is currently viewing.
    /// </summary>
    public ViewModelBase CurrentPage
    {
        get { return _currentPage; }
        private set
        {
            if (value != _currentPage)
            {
                if (_currentPage != null)
                    _currentPage.IsCurrentPage = false;
    
                _currentPage = value;
    
                if (_currentPage != null)
                    _currentPage.IsCurrentPage = true;
                RaisePropertyChanged(() => CurrentPage);
            }
        }
    }
    

    在您的 xaml 中,您可以在某些控制下绑定您的页面。假设我在 Border 元素中执行此操作。

    <!-- CURRENT PAGE AREA -->
    <Border Background="White" Grid.Column="1" Grid.Row="0">
        <HeaderedContentControl Content="{Binding Path=CurrentPage}" 
            Header="{Binding Path=CurrentPage.DisplayName}" />
    </Border>
    

    您可以像这样在资源中为视图模型定义视图:
    (部分完整的 XAML)

    <UserControl x:Class="BAT.View.BATWizardView"
            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:view="clr-namespace:BAT.View"
            xmlns:viewmodel="clr-namespace:BAT.ViewModel"
            mc:Ignorable="d" 
            d:DesignHeight="350" d:DesignWidth="600">
    
       <UserControl.Resources>
          <!-- These four templates map a ViewModel to a View. -->
          <DataTemplate DataType="{x:Type viewmodel:MyComparisonViewModel1}">
              <view:MyView1 />
          </DataTemplate>
    
          <DataTemplate DataType="{x:Type viewmodel:MyComparisonViewModel2}">
              <view:MyView2 />
          </DataTemplate>
    
       </UserControl.Resources>
       <Grid>
          <Border Background="White" Grid.Column="1" Grid.Row="0">
             <HeaderedContentControl Content="{Binding Path=CurrentPage}" 
                          Header="{Binding Path=CurrentPage.DisplayName}" />
          </Border>
       </Grid>
    </UserControl>
    

    看看是否有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 2017-09-18
      • 2011-04-14
      相关资源
      最近更新 更多