Search code examples
c#wpfxamlresourcedictionarycontentpresenter

Make use of WindowStyle from resource dictionary and add Buttons to a ControlPresenter in an application


I make use of a resource dictionary with all my styles, icons and more. Now I'd like to add my own titlebar implementing the title of the solution, my image and a ContentPresenter. When using the WindowStyle I'd like to add application specific items inside this ContentPresenter, but I don't know how to proceed.

This is my WindowStyle. Inside the Grid you'll find the ContentPresenter I'd like to fill.

<Style TargetType="{x:Type Window}" x:Key="tkDarkWindowStyle">
        <Setter Property="AllowsTransparency" Value="True"></Setter>
        <Setter Property="Foreground" Value="{StaticResource tkBrandBlueBrush}"></Setter>
        <Setter Property="Background" Value="{StaticResource exQuiteDarkBrush}"></Setter>
        <Setter Property="WindowStyle" Value="None"></Setter>
        <Setter Property="BorderThickness" Value="0"></Setter>
        <Setter Property="BorderBrush" Value="{StaticResource exQuiteDarkBrush}"></Setter>
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CaptionHeight="80" />
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Window">
                    <DockPanel LastChildFill="True">
                        <Border Background="{TemplateBinding Background}" DockPanel.Dock="Top" 
                            Height="80" x:Name="titlebar">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <DockPanel Grid.Column="0">
                                    <Path DockPanel.Dock="Left" Margin="10" Stretch="Uniform" Fill="{TemplateBinding Foreground}" Data="{Binding Source={StaticResource tkPrimaryLogo}}" VerticalAlignment="Center">
                                    </Path>
                                    <Label Content="{TemplateBinding Title}" Foreground="{TemplateBinding Foreground}" Margin="10" DockPanel.Dock="Left" FontSize="26" VerticalAlignment="Center"/>
                                </DockPanel>
                                <ContentPresenter Grid.Column="1"/>

                            </Grid>
                        </Border>
                        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="1" Padding="4">
                            <ContentPresenter/>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I used the style like this and tried to edit the template and add for example some buttons to the titlebar.

    <Window.Resources>
        <Style TargetType="{x:Type Window}" x:Key="newWindow"  BasedOn="{StaticResource tkDarkWindowStyle}">
            <!--here add application specific items? -->
        </Style>
    </Window.Resources>

How can I use the WindowStyle in my application and add specific items to the space i left at the titlebar?


Solution

  • Since the Window only has a single Content property, it makes no sense to include more than one <ContentPresenter /> element in the ControlTemplate.

    You may want to create a custom class that inherits from Window and adds a dependency property called "TitleBarContent" or something. You can then add a ContentControl to the template that binds to this property:

    <ContentControl Content="{TemplateBinding TitleBarContent}" />
    

    You can set the value of the dependency property in a style setter as usual:

    <Style TargetType="{x:Type local:YourWindowClass}" x:Key="newWindow"  BasedOn="{StaticResource tkDarkWindowStyle}">
        <Setter Property="TitleBarContent">
            <Setter.Value>
                <TextBlock>title...</TextBlock>
            </Setter.Value>
        </Setter>
    </Style>