WPF ListBoxItem, TreeViewItem und Button Templates  
Frank Dzaebel, erstellt am: 5.11.2007, zuletzt geändert:  25.5.2008
Kategorie: WPF Templates, .NET-Version: 3.0,

Es werden die Standard-Templates des WPF-ListBoxItemTreeViewItem und Button gezeigt.

Sie können sich die Standard-Templates der WPF-Controls durch folgenden Code aus folgenden Online-Samles anschauen:
[A Guide to the Microsoft® Windows® Presentation Foundation, Charles Petzold]
Dort im Chapter 25 im Projekt DumpControlTemplate. Wählen Sie ein Control und klicken Sie dann Dump an.
Siehe auch:
Button-Template [Windows Vista, unten] und Button-Template [Windows Classic, unten].
Interessant hier auch der Debugger Visualizer für den VisualTree:
Woodstock.

Control / ItemsControl / HeaderedItemsControl / TreeViewItem Control / ContentControl / ListBoxItem
<?xml version="1.0" encoding="utf-16" ?>
 <controltemplate targettype="TreeViewItem" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" MinWidth="19" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <ToggleButton IsChecked="False" ClickMode="Press" Name="Expander"> <ToggleButton.Style> <Style TargetType="ToggleButton"> <Style.Resources> <ResourceDictionary /> </Style.Resources> <Setter Property="UIElement.Focusable"> <Setter.Value> <s:Boolean>False</s:Boolean> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Width"> <Setter.Value> <s:Double>19</s:Double> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Height"> <Setter.Value> <s:Double>13</s:Double> </Setter.Value> </Setter> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Border Background="#00FFFFFF" Width="19" Height="13"> <Border BorderThickness="1,1,1,1" BorderBrush= "{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" Background= "{DynamicResource {x:Static SystemColors.WindowBrushKey}}" Width="9" Height="9" SnapsToDevicePixels="True"> <Path Data="M0,2L0,3 2,3 2,5 3,5 3,3 5,3 5,2 3,2 3,0 2,0 2,2z" Fill="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" Name="ExpandPath" Margin="1,1,1,1" /> </Border> </Border> <ControlTemplate.Triggers> <Trigger Property="ToggleButton.IsChecked"> <Setter Property="Path.Data" TargetName="ExpandPath"> <Setter.Value> <StreamGeometry>M0,2L0,3 5,3 5,2z</StreamGeometry> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ToggleButton.Style> </ToggleButton> <Border BorderThickness= "{TemplateBinding Border.BorderThickness}" Padding= "{TemplateBinding Control.Padding}" BorderBrush= "{TemplateBinding Border.BorderBrush}" Background= "{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True" Grid.Column="1"> <ContentPresenter Content= "{TemplateBinding HeaderedContentControl.Header}" ContentTemplate= "{TemplateBinding HeaderedContentControl.HeaderTemplate}" ContentSource="Header" Name="PART_Header" HorizontalAlignment= "{TemplateBinding Control.HorizontalContentAlignment}" SnapsToDevicePixels= "{TemplateBinding UIElement.SnapsToDevicePixels}" /> </Border> <ItemsPresenter Name="ItemsHost" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="TreeViewItem.IsExpanded"> <Setter Property="UIElement.Visibility" TargetName="ItemsHost"> <Setter.Value> <x:Static Member="Visibility.Collapsed" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>False</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="ItemsControl.HasItems"> <Setter Property="UIElement.Visibility" TargetName="Expander"> <Setter.Value> <x:Static Member="Visibility.Hidden" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>False</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="TreeViewItem.IsSelected"> <Setter Property="Panel.Background" TargetName="Bd"> <Setter.Value> <DynamicResource ResourceKey= "{x:Static SystemColors.HighlightBrushKey}" /> </Setter.Value> </Setter> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey= "{x:Static SystemColors.HighlightTextBrushKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="TreeViewItem.IsSelected"> <Condition.Value> <s:Boolean>True</s:Boolean> </Condition.Value> </Condition> <Condition Property="Selector.IsSelectionActive"> <Condition.Value> <s:Boolean>False</s:Boolean> </Condition.Value> </Condition> </MultiTrigger.Conditions> <Setter Property="Panel.Background" TargetName="Bd"> <Setter.Value> <DynamicResource ResourceKey= "{x:Static SystemColors.ControlBrushKey}" /> </Setter.Value> </Setter> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey= "{x:Static SystemColors.ControlTextBrushKey}" /> </Setter.Value> </Setter> </MultiTrigger> <Trigger Property="UIElement.IsEnabled"> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey= "{x:Static SystemColors.GrayTextBrushKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>False</s:Boolean> </Trigger.Value> </Trigger> </ControlTemplate.Triggers> </controltemplate>
<?xml version="1.0" encoding="utf-16" ?>
<controltemplate targettype="ListBoxItem"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:s="clr-namespace:System;assembly=mscorlib"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 <Border
  BorderThickness="{TemplateBinding Border.BorderThickness}"
  Padding="{TemplateBinding Control.Padding}"
  BorderBrush="{TemplateBinding Border.BorderBrush}"
  Background="{TemplateBinding Panel.Background}"
  Name="Bd"
  SnapsToDevicePixels="True">
  <ContentPresenter
   Content="{TemplateBinding ContentControl.Content}"
   ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
   HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
   VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
   SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
 </Border>
 <ControlTemplate.Triggers>
  <Trigger
   Property="Selector.IsSelected">
   <Setter
    Property="Panel.Background"
    TargetName="Bd">
    <Setter.Value>
     <DynamicResource
      ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
    </Setter.Value>
   </Setter>
   <Setter
    Property="TextElement.Foreground">
    <Setter.Value>
     <DynamicResource
      ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
    </Setter.Value>
   </Setter>
   <Trigger.Value>
    <s:Boolean>True</s:Boolean>
   </Trigger.Value>
  </Trigger>
  <MultiTrigger>
   <MultiTrigger.Conditions>
    <Condition
     Property="Selector.IsSelected">
     <Condition.Value>
      <s:Boolean>True</s:Boolean>
     </Condition.Value>
    </Condition>
    <Condition
     Property="Selector.IsSelectionActive">
     <Condition.Value>
      <s:Boolean>False</s:Boolean>
     </Condition.Value>
    </Condition>
   </MultiTrigger.Conditions>
   <Setter
    Property="Panel.Background"
    TargetName="Bd">
    <Setter.Value>
     <DynamicResource
      ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
    </Setter.Value>
   </Setter>
   <Setter
    Property="TextElement.Foreground">
    <Setter.Value>
     <DynamicResource
      ResourceKey="{x:Static SystemColors.ControlTextBrushKey}" />
    </Setter.Value>
   </Setter>
  </MultiTrigger>
  <Trigger
   Property="UIElement.IsEnabled">
   <Setter
    Property="TextElement.Foreground">
    <Setter.Value>
     <DynamicResource
      ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
    </Setter.Value>
   </Setter>
   <Trigger.Value>
    <s:Boolean>False</s:Boolean>
   </Trigger.Value>
  </Trigger>
 </ControlTemplate.Triggers>
</controltemplate>

Ein Template eines WPF-Objektes anschauen:   

private void Button_Click(object sender, RoutedEventArgs e)
{
  TemplateAnzeigen(((Button)sender).Template);
}

/// <summary>Zeigt das Template in XML in einem neuen Fenster an.</summary>
/// <param name="template">Zum Beispiel die Template-Eigenschaft des Controls</param>
private void TemplateAnzeigen(FrameworkTemplate template)
{
  Window w = new Window(); w.Title = "XAML ";
  // Verweis auf WindowsFormsIntegration.dll
  WindowsFormsHost wfh = new WindowsFormsHost(); 
  w.Height = 600; w.Width = 800;
  if (template is ControlTemplate)
    w.Title += "für ControlTemplate mit TargetType " + 
      ((ControlTemplate)template).TargetType.Name;
  else
    w.Title += "für " + template.GetType().Name;
  StackPanel sp = new StackPanel();
  System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
  wfh.Child = wb; w.Content = wfh;
  
  XmlWriterSettings settings = new XmlWriterSettings();
  settings.Indent = true;
  settings.IndentChars = new string(' ', 4);
  settings.NewLineOnAttributes = true;
  StreamWriter sw = new StreamWriter("template.xml", false, Encoding.UTF8);
  XmlWriter xw = XmlWriter.Create(sw, settings);
  XamlWriter.Save(template, xw); sw.Close();
  wb.Navigate(System.IO.Path.Combine(
    Directory.GetCurrentDirectory(),"template.xml"));
  w.ShowDialog();
}


Hier das interaktive Template des Buttons nach oben aufgeführter Methode mit dem Design [Windows Vista]:
 
<?xml version="1.0" encoding="utf-8"?>
<ControlTemplate
    TargetType="ButtonBase" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:s="clr-namespace:System;assembly=mscorlib" 
    xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
    <mwt:ButtonChrome
        Background="{TemplateBinding Panel.Background}"
        BorderBrush="{TemplateBinding Border.BorderBrush}"
        RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
        RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
        RenderPressed="{TemplateBinding ButtonBase.IsPressed}"
        Name="Chrome"
        SnapsToDevicePixels="True">
        <ContentPresenter
            RecognizesAccessKey="True"
            Content="{TemplateBinding ContentControl.Content}"
            ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
            Margin="{TemplateBinding Control.Padding}"
            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </mwt:ButtonChrome>
    <ControlTemplate.Triggers>
        <Trigger
            Property="UIElement.IsKeyboardFocused">
            <Setter
                Property="mwt:ButtonChrome.RenderDefaulted"
                TargetName="Chrome">
                <Setter.Value>
                    <s:Boolean>True</s:Boolean>
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="ToggleButton.IsChecked">
            <Setter
                Property="mwt:ButtonChrome.RenderPressed"
                TargetName="Chrome">
                <Setter.Value>
                    <s:Boolean>True</s:Boolean>
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="UIElement.IsEnabled">
            <Setter
                Property="TextElement.Foreground">
                <Setter.Value>
                    <SolidColorBrush>#FFADADAD</SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>False</s:Boolean>
            </Trigger.Value>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>


Hier das interaktive Template des Buttons nach oben aufgeführtem Code mit dem Design [Windows Classic]:

<?xml version="1.0" encoding="utf-8"?>
<ControlTemplate
    TargetType="ButtonBase" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:s="clr-namespace:System;assembly=mscorlib" 
    xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <mwt:ClassicBorderDecorator
        Background="{TemplateBinding Panel.Background}"
        BorderStyle="Raised"
        BorderBrush="{TemplateBinding Border.BorderBrush}"
        BorderThickness="3,3,3,3"
        Name="ContentContainer"
        SnapsToDevicePixels="True">
        <ContentPresenter
            RecognizesAccessKey="True"
            Content="{TemplateBinding ContentControl.Content}"
            ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
            Margin="{TemplateBinding Control.Padding}"
            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </mwt:ClassicBorderDecorator>
    <ControlTemplate.Triggers>
        <Trigger
            Property="UIElement.IsKeyboardFocused">
            <Setter
                Property="mwt:ClassicBorderDecorator.BorderStyle"
                TargetName="ContentContainer">
                <Setter.Value>
                    <x:Static
                        Member="mwt:ClassicBorderStyle.RaisedFocused" />
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="Button.IsDefaulted">
            <Setter
                Property="mwt:ClassicBorderDecorator.BorderStyle"
                TargetName="ContentContainer">
                <Setter.Value>
                    <x:Static
                        Member="mwt:ClassicBorderStyle.RaisedFocused" />
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="ButtonBase.IsPressed">
            <Setter
                Property="mwt:ClassicBorderDecorator.BorderStyle"
                TargetName="ContentContainer">
                <Setter.Value>
                    <x:Static
                        Member="mwt:ClassicBorderStyle.RaisedPressed" />
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="ToggleButton.IsChecked">
            <Setter
                Property="mwt:ClassicBorderDecorator.BorderStyle"
                TargetName="ContentContainer">
                <Setter.Value>
                    <x:Static
                        Member="mwt:ClassicBorderStyle.RaisedPressed" />
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
        <Trigger
            Property="UIElement.IsEnabled">
            <Setter
                Property="TextElement.Foreground">
                <Setter.Value>
                    <DynamicResource
                        ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>False</s:Boolean>
            </Trigger.Value>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>