Same header & footer in all WPF windows

后端 未结 4 1869
终归单人心
终归单人心 2021-01-14 07:48

In my project I have same header & footer for all windows (I have more then 20 wpf windows in this project), Only Content has changed. This is WPF project. If its a asp.

相关标签:
4条回答
  • 2021-01-14 07:54

    Step 1: Define your window style with header and footer in app.xaml or in shared 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>
    

    Step 2: Set Style to windows.

    Style="{StaticResource HeaderFooterWindowStyle}"
    
    0 讨论(0)
  • 2021-01-14 07:58

    Why not creating your own "MyWindow" class deriving from a regular Window?

    It's a fair common practice whereas you need to override/customize the standard Window component. After you have the new component, you should write a custom template so that any Content will be displayed in your desired fashion.

    Have a look here: http://msdn.microsoft.com/en-us/library/aa969824(v=vs.110).aspx

    0 讨论(0)
  • 2021-01-14 08:09

    I suppose you need to specify Footer and Header in each window, but you want to have consistent look & feel.

    In general, if you want to add some reusable visual stuff around content, you should use content control and edit its template.

    If you need to specify also header for the content, you should use HeaderedContentControl and edit it's template.

    If you need to specify also footer, just create you own control inherited from HeaderedContentControl and specify Footer property.

    here is expampe of usage:

    <controls:HeaderFooterContentControl 
        Header="Some simple header" 
        Footer="There could be xaml footer as well!>
        <Grid>
            <!--Place your content here-->
        </Grid>
    </controls:HeaderFooterContentControl>
    

    and implementation:

    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));
    }
    

    and the template:

    <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>
    

    Notice, that this have nothing to do with MVVM, but since Header and Footer are dependency properties, it could be easily used in any MVVM scenario.

    I would definitely avoid binding to viewmodel properties in ControlTemplate if possible.

    0 讨论(0)
  • 2021-01-14 08:10

    I'm not a 100% sure what do you mean by "all windows", but a good approach would be to have a header and a footer UserControls.

    You can set them whichever way you want, (text, colors, etc), and then, in all your windows you could have a grid with 3 elements, stackpanel, dockpanel, whatever you want, which will have the header, then your content, and last, your footer.


    Edit: As per comment: Instead of having this:

    <Window ...>
        <StackPanel>
            <Label>one</Label>
            <Label>two </Label>
            <Label>three</Label>
        </StackPanel>
    </Window>
    

    You can have a UserControls (lets say called HeaderControl), and then all you need to do is

    1. Add the namespace so you can use it.
    2. Add it like you'll add any other control.
    3. Enjoy reusability.

    steps explanation:

    1. Add this to your windown with the rest of the xmlns.... definitions:
      xmlns:controls="clr-namespace:WpfApplication1"

    2. Changing the first control from label to our resource:
      Instead of <Label>one</Label> write: <controls:HeaderControl />

    example

    0 讨论(0)
提交回复
热议问题