C# wpf style implements PART replaceable areas

Posted by biopv on Tue, 09 Nov 2021 22:28:59 +0100

preface

Some styles are defined in style, such as the external style of the container (such as customizing the window title bar. At this time, the window is the container and the title bar is the external style). When using, you can only place controls inside the container. At this time, it is not necessary to add controls to the external style of the container. But sometimes it is necessary to make some personalized customization in different pages, but the overall framework is the same. It is obviously unscientific to write redundant code on each page. When the overall interface framework is consistent, the method of local layout customization can be done, which is the content of this paper.

1, What is a PART replaceable area?

It has been roughly explained in the preface that label replacement can be freely specified outside an area specified in style. Here are two examples to illustrate the customizable area.

1.wpf source code example

wpf's ScrollBar has such an area. The Track of ScrollBar is a customizable area. The usage method is that the x:Name value in the Template is part_ The Track tag of Track will become the Track binding event of ScrollBar. The source code fragments are as follows:

Find part when setting Template_ Track.

ScrollBar source code can refer to referencesource
The schematic diagram is as follows:

The ScrollBar structure can be referenced Detailed explanation of C# wpf ScrollBar custom styles

2. Practical application examples

A series of windows with the same overall interface framework but different parts are as follows.

2, How?

Define two additional properties, ShiftFrom and ShiftElementName. ShiftFrom specifies the source control or parent control, and ShiftElementName specifies the control name. After the property is set, get the control specified by ShiftFrom, find the control with its internal name of ShiftElementName, remove it, and add it to the container control with the specified additional property.

3, Complete code

4, Use example

The template of style is defined as follows:

<ControlTemplate TargetType = "{x:Type Window}" >
    <Grid >
        <!--Title Block-->
        <Grid Background="Gray" Height="50">
            <!--Replaceable area,Set client area CP_Content of PART_Title Control can be transferred under this container-->
            <Grid local:WindowStyles.ShiftFrom="{Binding Content, ElementName=CP_Content }"   local:WindowStyles.ShiftElementName="PART_Title"></Grid>
            <!--Minimize, maximize, etc...-->
        </Grid>
        <!--Client area-->
        <ContentPresenter Name = "CP_Content" Grid.Row="1"/>
    </Grid>
</ControlTemplate>

1. Menu window

code:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApp1"     
        mc:Ignorable="d"
        Title="MainWindow" Height="720" Width="1280"
        Style="{DynamicResource WindowStyle_Normal_Gray}"      
        >
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="WindowStyles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Background="White">
        <!--Replace title block area-->
        <Button x:Name="PART_Title" HorizontalAlignment="Left"  Width="120" Height="50" Content="file(F)"  Background="#666666"  Foreground="White"  FontSize="24"  Cursor="Hand">
            <Button.Template  >
                <ControlTemplate TargetType="Button" >
                    <Border Background="{TemplateBinding Background}">
                        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"  Text="{TemplateBinding Content}"  Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}"></TextBlock>
                    </Border>
                </ControlTemplate>
            </Button.Template>
        </Button>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#999999" FontSize="64" Text="Hello Word!"></TextBlock>
    </Grid>
</Window>    

Effect preview:

2. Title window

code:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApp1"     
        mc:Ignorable="d"
        Title="MainWindow" Height="720" Width="1280"
        Style="{DynamicResource WindowStyle_Normal_Gray}"      
        >
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="WindowStyles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Background="White">
        <!--Replace title block area-->
        <TextBlock x:Name="PART_Title" HorizontalAlignment="Center"  VerticalAlignment="Center"  Text="Hello Word Window" FontWeight="Bold"  Foreground="White"  FontSize="24"   >
        </TextBlock>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#999999" FontSize="64" Text="Hello Word!"></TextBlock>
    </Grid>
</Window>    

Effect preview:

summary

The method described in this paper effectively improves the reusability of style, makes the definition of style more flexible, and solves a kind of code redundancy problem. However, this method also has some disadvantages. Because it is the control replacement by calling cs code at run time, the effect seen by the designer is inconsistent with the actual operation. Moreover, after using this method, the page code will depend on style and cannot switch style at will, unless it is also the style using this method. In general, this method is still useful, and it can reduce a lot of redundant code workload for the use of actual projects.

Topics: C# WPF