Like you, when I started and wanted to understand how / what happens and works with templates, it required a lot of trial and error. I hope my research and some step-by-step components will help you customize to your taste and KNOW where things come from.
First, trying to understand how the new “template style” will work, I created a simple standalone WPF application (“AMS”) for my Any Manipulating Styles. So I don’t have to wait long to see what the trial / error will look like with the rest of my main project and topic.
From this, I created a new WPF window called "TestingStyles". Save / Compile, run, no problem.
Now, in the "VIEW CODE" window of TestingStyles, I have set everything I play for a custom class ... To show step by step, I created the following:
namespace AMS { /// <summary> /// Interaction logic for TestingStyles.xaml /// </summary> public partial class TestingStyles : Window { public TestingStyles() { InitializeComponent(); } } // Enumerator for a custom property sample... public enum HowToShowStatus { ShowNothing, ShowImage1 } public class YourCustomButtonClass : Button { public YourCustomButtonClass() { // auto-register any "click" will call our own custom "click" handler // which will change the status... This could also be done to simplify // by only changing visibility, but shows how you could apply via other // custom properties too. Click += MyCustomClick; } protected void MyCustomClick(object sender, RoutedEventArgs e) { if( this.ShowStatus == HowToShowStatus.ShowImage1 ) this.ShowStatus = HowToShowStatus.ShowNothing; else this.ShowStatus = HowToShowStatus.ShowImage1; } public static readonly DependencyProperty ShowStatusProperty = DependencyProperty.Register("ShowStatus", typeof(HowToShowStatus), typeof(YourCustomButtonClass), new UIPropertyMetadata(HowToShowStatus.ShowNothing)); public HowToShowStatus ShowStatus { get { return (HowToShowStatus)GetValue(ShowStatusProperty); } set { SetValue(ShowStatusProperty, value); } } } }
As you can see, the custom class is "Button", I have a lower border above the standard declaration of TestingStyles: Window ... so that it is all in the same "Project".
In this XAML example, I refer to the graphic file "TaskComplete.png" (which should be added only for trial purposes, add directly to the project ... Even if a simple emoticon for trial purposes). So, create such a simple .png file ... even with Microsoft Paint and drawing a circle with your eyes and a smile. Save the project in the root folder (first go to it, start it first).
Save and recompile the project so that the project knows the new “class” (button) when you start defining the XAML template.
Now, back to the TestingStyles design and move on to the split screen so you can see both the constructor and the XAML markup ... and just replace it with the following ...
<Window x:Class="AMS.TestingStyles" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:AMS" Title="TestingStyles" Height="300" Width="300" > <Window.Resources> <Style TargetType="my:YourCustomButtonClass" x:Key="keyYourCustomButtonClass"> <Setter Property="BorderThickness" Value="1"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Padding" Value="0,0,1,1"/> <Setter Property="Width" Value="100" /> <Setter Property="Height" Value="30" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button" > <Border x:Name="BorderTopLeft" BorderBrush="Gainsboro" BorderThickness="0,0,1.5,1.5"> <Border x:Name="BorderBottomRight" BorderBrush="Gray" BorderThickness="1.5,1.5,0,0"> <Grid Background="LightBlue" > <Grid.ColumnDefinitions> <ColumnDefinition Width="20px" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <Image x:Name="btnImage" Grid.Row="0" Grid.Column="0" Stretch="None" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Source="TaskComplete.png" Visibility="Visible" /> <TextBlock x:Name="txtNewBtn" Grid.Row="0" Grid.Column="1" Padding="5" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{TemplateBinding Content}" /> </Grid> </Border> </Border> <ControlTemplate.Triggers> <Trigger Property="IsPressed" Value="true"> <Setter Property="Margin" Value="1,1,0,0"/> <Setter TargetName="BorderTopLeft" Property="BorderThickness" Value="2.5,2.5,0,0"/> <Setter TargetName="BorderBottomRight" Property="BorderThickness" Value="0,0,.5,.5"/> </Trigger> <DataTrigger Binding="{Binding Path=ShowStatus, RelativeSource={RelativeSource Self}}" Value="ShowNothing"> <Setter TargetName="btnImage" Property="Visibility" Value="Hidden"/> </DataTrigger> <DataTrigger Binding="{Binding Path=ShowStatus, RelativeSource={RelativeSource Self}}" Value="ShowImage1"> <Setter TargetName="btnImage" Property="Visibility" Value="Visible"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style TargetType="my:YourCustomButtonClass" BasedOn="{StaticResource keyYourCustomButtonClass}" /> </Window.Resources> <Grid> <my:YourCustomButtonClass Content="Button" VerticalAlignment="Top" ShowStatus="ShowImage1" /> </Grid> </Window>
This should give you a big step forward to define your own patterns and how the elements begin to link together. When this pattern is started, as any colors, margins, indents, etc. change. To the template, you will immediately see the visual impact of this component on the control.
Have fun and don't bang your head too hard against the wall ...
BTW, as soon as this works, you can take the style element in
<Window.Resources> </Window.Resources>
and put it in the Windows Resource Dictionary to make it global for your project, not just this test form.