【发布时间】:2020-10-07 13:07:38
【问题描述】:
在我的项目中,所有窗口都有相同的页眉和页脚(我在这个项目中有超过 20 个 wpf 窗口),只有内容发生了变化。这是 WPF 项目。如果它是一个 asp.net,我在其中使用了母版页。
现在我复制粘贴页眉和页脚所有窗口。如果 Header 需要任何小的更改,我必须在所有 Windows 标题中进行。有什么解决办法吗?
【问题讨论】:
在我的项目中,所有窗口都有相同的页眉和页脚(我在这个项目中有超过 20 个 wpf 窗口),只有内容发生了变化。这是 WPF 项目。如果它是一个 asp.net,我在其中使用了母版页。
现在我复制粘贴页眉和页脚所有窗口。如果 Header 需要任何小的更改,我必须在所有 Windows 标题中进行。有什么解决办法吗?
【问题讨论】:
我不是 100% 确定“所有窗口”是什么意思,但一个好的方法是拥有一个 header 和一个 footer 用户控件。
您可以随意设置它们(文字、颜色等),
然后,在你的所有窗口中,你可以有一个包含 3 个元素的网格,stackpanel、dockpanel,任何你想要的,其中将有 header,然后是你的 content,最后是你的 footer。
编辑: 根据评论:而不是这样:
<Window ...>
<StackPanel>
<Label>one</Label>
<Label>two </Label>
<Label>three</Label>
</StackPanel>
</Window>
您可以拥有一个 UserControls(假设称为 HeaderControl),然后您需要做的就是
步骤说明:
将此与其余的 xmlns.... 定义一起添加到您的窗口中:xmlns:controls="clr-namespace:WpfApplication1"
将第一个控件从标签更改为我们的资源:
而不是 <Label>one</Label> 写:<controls:HeaderControl />
【讨论】:
第 1 步:在 app.xaml 或共享 ResourceDictionary 中使用页眉和页脚定义窗口样式。
<Style x:Key="HeaderFooterWindowStyle" TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Header -->
<Border Grid.Row="0" Background="Red">
<TextBlock Text="Header"/>
</Border>
<!-- Body -->
<ContentPresenter Grid.Row="1"/>
<!-- Footer -->
<Border Grid.Row="2" Background="Red">
<TextBlock Text="Footer"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
第 2 步:将样式设置为 windows。
Style="{StaticResource HeaderFooterWindowStyle}"
【讨论】:
为什么不创建您自己的从常规窗口派生的“MyWindow”类?
这是一种相当普遍的做法,而您需要覆盖/自定义标准 Window 组件。有了新组件后,您应该编写一个自定义模板,以便任何内容都将以您想要的方式显示。
看看这里:http://msdn.microsoft.com/en-us/library/aa969824(v=vs.110).aspx
【讨论】:
我想您需要在每个窗口中指定页脚和页眉,但您希望具有一致的外观。
一般来说,如果你想在内容周围添加一些可重用的视觉效果,你应该使用内容控件并编辑它的模板。
如果您还需要为内容指定标题,您应该使用 HeaderedContentControl 并编辑它的模板。
如果您还需要指定页脚,只需创建您自己的从 HeaderedContentControl 继承的控件并指定页脚属性。
这里是使用的expampe:
<controls:HeaderFooterContentControl
Header="Some simple header"
Footer="There could be xaml footer as well!>
<Grid>
<!--Place your content here-->
</Grid>
</controls:HeaderFooterContentControl>
和实施:
public class HeaderFooterContentControl : HeaderedContentControl
{
public object Footer
{
get { return (object) GetValue(FooterProperty); }
set { SetValue(FooterProperty, value); }
}
public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof (object), typeof (HeaderFooterContentControl));
}
和模板:
<Style TargetType="controls:HeaderFooterContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:HeaderFooterContentControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="White">
<ContentControl Content="{TemplateBinding Header}" Foreground="Red"
ContentTemplate="" />
</Border>
<Border Grid.Row="1" Background="Red">
<ContentControl Content="{TemplateBinding Content}" Foreground="White"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
</Border>
<Border Grid.Row="2" Background="White">
<ContentControl Content="{TemplateBinding Footer}" Foreground="Red" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
请注意,这与 MVVM 无关,但由于 Header 和 Footer 是依赖属性,因此可以在任何 MVVM 场景中轻松使用。
如果可能的话,我肯定会避免绑定到 ControlTemplate 中的视图模型属性。
【讨论】: