在学习ControlTemplate示例时,发现有一些template中元素名称以PART_开头,在《Windows Presentation Foundation Unleashed》中也提到了。

在WPF自带的templdate中有很多以PART_开头的元素,这些元素都是用TemplatePartAttribute标记过,表示如果用户想自定义模版,必须提供同名及同类型的元素。原因是WPF自带的控件后台逻辑会与这些元素交互,比如ProgressBar中的进度条长度,这个是动态的,由后台代码指定的,再比如ComboBox,下拉列表,这个是Popup元素构成的,我们在实现template时,也有一定包含同名的Popup元素,也就是PART_Popup。周银辉的文章写的挺好。

如果不提供同名,同类型的元素,那就需要自己处理相关的逻辑,需要额外的工作量。比如《Windows Presentation Foundation Unleashed》中实现的圆形的ProgressBar。

《Windows Presentation Foundation Unleashed》中提到的PART_打头的控件:
ProgressBar中的PART_Indicator和PART_Track,用来保证进度条能正确的显示当前进度。

<ResourceDictionary 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Shared.xaml" />
  </ResourceDictionary.MergedDictionaries>

  <!-- SimpleStyles: ProgressBar -->
  <!--<SnippetProgressBar>-->
    <!--Background="{StaticResource PressedBrush}"-->
    <!--Background="{StaticResource DarkBrush}"-->
    <Style x:Key="{x:Type ProgressBar}"
       TargetType="{x:Type ProgressBar}">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type ProgressBar}">
          <Grid MinHeight="14" MinWidth="200">
            <Border 
              Name="PART_Track" 
              CornerRadius="2" 
              
              Background ="Blue"
              BorderBrush="{StaticResource SolidBorderBrush}"
              BorderThickness="1" />
            <Border 
              Name="PART_Indicator" 
              CornerRadius="2" 
              Background="Red"
              BorderBrush="{StaticResource NormalBorderBrush}" 
              BorderThickness="1" 
              HorizontalAlignment="Left" />
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
  <!--</SnippetProgressBar>-->
</ResourceDictionary>

 

image

ComboBox中Popup元素名为PART_Popup,使得ComboBox的DropDownClosed事件能正常响应。为名PART_EditableTextBox的是TextBox,允许用户输入。

TextBox中必须有一个名为PART_ContentHost的元素,类型为ScrollViewerAdornerDecorator

有哪些内部定义的元素被指定了TemplatePartAtrribute呢,可以在WPF Control库中查到,比如ProgressBar
定义如下:
[TemplatePartAttribute(Name = "PART_Track", Type = typeof(FrameworkElement))]
[TemplatePartAttribute(Name = "PART_Indicator", Type = typeof(FrameworkElement))]
public class ProgressBar : RangeBase

MSDN上的ControlTemplate示例也是很好的学习参考。