For example, i have the following Style:
<Style x:Key="MyStyle" TargetType="MyType">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MyType">
<Grid>
<Button x:Name="MyButton"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is it possible to inherit from him a different style and change the properties of the button "MyButton"? For example change the property Visibility?
Thank You!
There are more than one way of achieving this.
Use BasedOn
<Style TargetType="MyChildType" BasedOn="{StaticResource MyStyle}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MyType">
<Grid>
<Button x:Name="MyButton" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Apply style to MyButton and put Trigger in Style.Triggers to change the properties of button depending on the properties of parent
Related
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, as illustrated in the example below.
Lets redefine the ControlTemplate of a Label with a TextBlock named «MyTextBlock»
<Style x:Key="MyLabel" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock x:Name="MyTextBlock"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Lets inherit the style of the previously defined Label
<Style x:Key="MyNewLabel" BasedOn="{StaticResource MyLabel}">
<Setter Property="{Binding {[SOME.EXPRESSION.TO.REACH.MyTextBlock???]}, Path=Foreground}" Value="Red" />
</Style>
Regards
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>
I'm trying to create a new style for a ListItem to get rid of the default blue rectangles showing when hovering the items and selecting them.
here's what I've got so far:
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<ContentPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Problem is - content is not showing at all. I tried to do it with a different controller (a button, for example). ContentPresenter doesn't seem to work with ListBoxItem though...
How do I achieve that?
You need to add TargetType="ListBoxItem" to ControlTemplate
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<StackPanel Orientation="Horizontal">
<ContentPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
this is the image
I need Button Control Template as shown in the image.So can anyone help me to do it?
This piece of code in your app.xaml
<Application.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image Source="DHXMR.jpg" />
<ContentControl Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
will turn out to show buttons like that:
Of course you need to remove the white "Button" text from the sample image you provided in your link - but I guess you're able to do that on your own
I am new to WPF and I created the following simple style example. But it doesn't work properly and button's content doesn't show although I can still click on it. Can anyone tell me why it is broken?
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid" x:Name="GridWithMarginStyle">
<Setter Property="Margin" Value="12"></Setter>
</Style>
</Window.Resources>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<EventSetter Event="Button.Click" Handler="ButtonHandler" />
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
</StackPanel.Resources>
<Button Name="OkBtn">OK</Button>
<Button Name="CancelBtn" Click="CancelBtn_Click">Cancel</Button>
</StackPanel>
You are using the BasedOn property in the correct way. The problem is that your ContentPresenter is not binded to the control it renders (i.e. the button).
Just try to replace your ControlTemplate XAML with this one:
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
By using TemplateBinding you can bind the ContentPresenter to the Content property of your templated control.
I'm using a ControlTemplate for defining the appearance of my buttons in a WPF application. Additionally I would like to use styles to set certain aspects of my buttons. These styles should set properties on elements defined in the ControlTemplate, like (simplified):
<Window.Resources>
<ControlTemplate x:Key="Template1" TargetType="Button">
<Grid>
<Rectangle Name="rect" Fill="White" Stroke="Blue" StrokeThickness="2"/>
<TextBlock Name="text" Text="Hallo" Foreground="Red" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
<Style x:Key="Style1" TargetType="Button" >
<Setter TargetName="rect" Property="Fill" Value="Red"/>
</Style>
</Window.Resources>
Now the compiler complains that the TargetName "rect" isn't a valid target which I can understand since an untemplatized Button doesn't contain an element named "rect".
I know that I could change the style to setting the complete template, but I would like to avoid that (because the template is much more complex than shown here and I do not want to duplicate it for each style...)
Is it possible to achieve this behaviour? Perhaps by setting the TargetType right? Any other ideas?
You can NOT override only part of the control template. You can either change everything or nothing.
You can have setters for properties on the style though.
The standard pattern is to use TemplateBinding in the control template to bind to properties of the control itself, and then set the properties on the control in the style. For example:
<Window.Resources>
<ControlTemplate x:Key="Template1" TargetType="Button">
<Grid>
<Rectangle Name="rect" Fill="{TemplateBinding Background}" Stroke="Blue" StrokeThickness="2"/>
<TextBlock Name="text" Text="Hallo" Foreground="Red" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
<Style x:Key="Style1" TargetType="Button" >
<Setter Property="Background" Value="Red"/>
</Style>
</Window.Resources>
This will bind the Fill property on rect to the Background property on the Button. The style will set the Background property to Red, which will cause the Fill to be set to Red.
In order to set defaults, you would normally create a style that set the template as well as the other properties:
<Window.Resources>
<Style x:Key="BaseStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle Name="rect" Fill="{TemplateBinding Background}" Stroke="Blue" StrokeThickness="2"/>
<TextBlock Name="text" Text="Hallo" Foreground="Red" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="White"/>
</Style>
<Style x:Key="Style1" TargetType="Button" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Background" Value="Red"/>
</Style>
</Window.Resources>
The first style will apply the template and set Background to White, so the rectangle will be white. The second style inherits from the first one but sets the Background to Red, so the rectangle will be red.