我想制作一个类似于任何网站中使用的布局 - 标题,侧边栏和页脚保持不变,但中心部分。我有多个页面/窗口在wpf混合C#应用程序中显示,它们完全不同。例如,stackoverflow具有主页的布局和每个问题的另一个布局。这是另一个例子:
我必须在之前的项目中执行此操作并使用单个网格布局,然后,对于每个页面,我必须隐藏()所有这些并显示每个项目位于顶部 -
诀窍是什么?如何在wpf应用程序中执行相同的操作?在一个典型的C#应用程序中,我每次都必须打开一个子窗口,但这些日子看起来很难看。
提前谢谢!
答案 0 :(得分:6)
如果您要在WPF中使用Page
,那么您需要阅读MSDN上的Navigation Overview页面。简而言之,您可以使用NavigationService
Class在WPF应用程序中的Page
之间导航。要从后面的代码更改页面,您可以执行以下操作:
NextPage page = new NextPage();
NavigationService.Navigate(page);
要让用户更改Page
,您可以使用<{1}}中的Hyperlink
Class :
Page
要设置所需的页面,您必须将<Hyperlink NavigateUri="pack://application:,,,/AppName;component/Pages/NextPage.xaml">
Navigate to Next Page
</Hyperlink>
加载到Frame
,然后可以在Page
中随意布局:
MainWindow.xaml
答案 1 :(得分:4)
听起来你需要一个自定义的usercontrol和一些数据绑定。
您可以将XAML中的DataTemplates声明为模型类型为key的资源,以便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层决定中间的内容。希望这很清楚,如果没有,请给我一个喊叫,我会尝试扩展它!
答案 2 :(得分:1)
假设我有主视图模型,我在其中创建了一个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>
看看是否有帮助。