WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?
You can base a Style on another Style and override specfic setters:
<Style x:Key="myStyle" TargetType="xctk:ColorPicker" BasedOn="{StaticResource {x:Type xctk:ColorPicker}}">
<!-- This will override the Background setter of the base style -->
<Setter Property="Background" Value="Red" />
</Style>
But you cannot "override" only a part of a ControlTemplate. Unfortunately you must then (re)define the entire template as a whole.
Replace part of default template in WPF
Unfortunately, I think you have to replace the entire template:
From MSDN: http://msdn.microsoft.com/en-us/library/aa970773.aspx
Controls in Windows Presentation
Foundation (WPF) have a
ControlTemplate that contains the
visual tree of that control. You can
change the structure and appearance of
a control by modifying the
ControlTemplate of that control. There
is no way to replace only part of the
visual tree of a control; to change
the visual tree of a control you must
set the Template property of the
control to its new and complete
ControlTemplate.
Style BasedOn a style defined in ControlTemplate Resources
This is not possible since you can't base a ControlTemplate
on another ControlTemplate
. You will have to re-define the entire template as a whole:
WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?
And adding a trigger to a Style
won't affect or "override" the triggers that are defined in the ControlTemplate
of the control so you will have to override the entire ControlTemplate
from scratch.
You could of course copy the default one into your XAML markup and edit it as per your requirements.
WPF XAML Change Style Template Property for Some Elements
I would write a custom control that looks something like this:
internal class IconButton : Button
{
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(IconButton), new PropertyMetadata(null));
}
Then edit your style to accommodate it:
<Style TargetType="{x:Type location:IconButton}" x:Key="ButtonEllipse">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type location:IconButton}">
<StackPanel Orientation="Vertical">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 0 0 10"/>
<Image x:Name="ButtonImage" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None" Source="{TemplateBinding Source"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
Where location is a xaml-defined namespace where the IconButton class is placed.
Then just set the Source
property of your button. You can mess around with the Source property to set a default as well.
How do I access an element of a parent template style in XAML?
I am having trouble accessing a named element of a parent template style in WPF.
This is not possible. You can't base a ControlTemplate
on another ControlTemplate
.
I am afraid you will have to re-define the entire ControlTemplate
from scratch in the derived Style
if you want the setter to be able find the CurrentImage
element that is defined in the template of the base Style
.
WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?
But instead of using a ControlTemplate
trigger, you should be able to use a Style
trigger that sets the Image
property of the control itself rather than setting the Source
property of the Image
element in the template:
<Style x:Key="ButtonCustomStyle" TargetType="{x:Type local:ImageButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ImageButton}">
<Grid>
<Image Source="{TemplateBinding Image}" Stretch="Fill" x:Name="CurrentImage"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Image" Value="{Binding ImageHover, RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type local:ImageButton}"
BasedOn="{StaticResource ButtonCustomStyle}"
x:Key="Disableable">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Image" Value="\Images\disabled.png"/>
</Trigger>
</Style.Triggers>
</Style>
WPF Styles and Polymorphism
You can base a Style
on Another (one only!) Style
using the BasedOn
property and override specific properties, but you cannot base a DataTemplate
or a ControlTemplate
on another template. This is not supported. A template must be defined as a whole:
WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?
WPF, changing style of element inside ControlTemplate
I'm wondering if WPF offers a way to change the style of a named element defined inside a ControlTemplate, from a style declared somewhere else
Short answer: No.
You cannot access or set a property of the element (TextBlock
) directly but you may set a property of the styled control (Label
) that you bind to the element in the template, e.g.:
<Style x:Key="MyLabel" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock x:Name="MyTextBlock" Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MyNewLabel" TargetType="Label" BasedOn="{StaticResource MyLabel}">
<Setter Property="Foreground" Value="Red" />
</Style>
Related Topics
How to Sort an Observable Collection
"Could Not Load Type [Namespace].Global" Causing Me Grief
Change Route Collection of MVC6 After Startup
Authorization Header Is Lost on Redirect
Default Parameter for Value Must Be a Compile Time Constant
Retrieving Creation Date of File (Ftp)
What Really Happens in a Try { Return X; } Finally { X = Null; } Statement
Why Is Inserting Entities in Ef 4.1 So Slow Compared to Objectcontext
How to Get Duplicate Items from a List Using Linq
How to Programmatically Modify Wcf App.Config Endpoint Address Setting
One to One Optional Relationship Using Entity Framework Fluent API
Linq to Entities Only Supports Casting Edm Primitive or Enumeration Types with Ientity Interface
Determine What Control the Contextmenustrip Was Used On
How to Get a List of All Routes in ASP.NET Core
Why Are the Properties of Anonymous Types in C# Read-Only