I have a style for a progressbar that shows some text only on the PART_Indicator section:
<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="15" Background="{StaticResource PressedBrush}" BorderBrush="{StaticResource SolidBorderBrush}" BorderThickness="1" />
<Border Name="PART_Indicator" CornerRadius="15" Background="#CEAC2D" BorderBrush="#CEAC2D" BorderThickness="1" HorizontalAlignment="Left" >
<Viewbox>
<TextBlock TextAlignment="Center" Background="Transparent" FontFamily="Times" Foreground="Black" Margin="2,2,2,2"
Text="{Binding ProgressText}"/>
</Viewbox>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have a few bars and each one should show a different kind of text (50%, 2/8, etc..) and that of course is handled by the VM.
My question is how to use this style for all the bars but differentiate only that textblock text. I presume the binding is not correct .. I probably need a TemplateBinding, but to what property?
So this is my SliderThumbStyle Style:
<Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Border Name="outerBorder"
Background="{DynamicResource LabelDisableForegroundColor}"
BorderBrush="{DynamicResource LabelDisableForegroundColor}"
Height="20"
Width="20"
Opacity="1"
BorderThickness="2"
CornerRadius="8"/>
<TextBlock x:Name="sliderValue"
FontSize="11"
Foreground="Silver"
Text="{Binding }"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And as you can see i put inside the Thumb a simple TextBlock in oder to see the current Slider value
What i need to put inside the Text property:
Text="{Binding }"
This should work provided that the Thumb is a visual child of the Slider:
<TextBlock Text="{Binding Value, RelativeSource={RelativeSource AncestorType=Slider}}" />
I have a custom button Style written in XAML. It is a button with image and text.
But the Image should be customizable. I need to change the Source property in designer.
My code:
<Window.Resources>
<ResourceDictionary>
<Style x:Key="SSbutton" TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Viewbox Stretch="Uniform">
<Border Background="{TemplateBinding Background}" Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<!--I want to change this Source property-->
<Image Source="img/desktop.png" Width="30" HorizontalAlignment="Left" />
<TextBlock Margin="3,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Center"
Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}"/>
</StackPanel>
</Border>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.Row="1" Background="LightGreen">
<StackPanel >
<Button Style="{StaticResource SSbutton}" Width="90" Height="30" Content="Desktop" FontSize="13"
Foreground="White"/>
</StackPanel>
</Border>
</Grid>
How can I do that?
Piggy back in to the property using an arbitrary template binding with the handy dandy Tag property;
<Style x:Key="SSbutton" TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="Green"/>
<!-- Set a default -->
<Setter Property="Tag" Value="img/desktop.png"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Viewbox Stretch="Uniform">
<Border Background="{TemplateBinding Background}" Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<!--I want to change this Source property-->
<Image Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Width="30" HorizontalAlignment="Left" />
<TextBlock Margin="3,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Center"
Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}"/>
</StackPanel>
</Border>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then at the instance;
<Button Style="{StaticResource SSbutton}"
Tag="Some/Other/Image.png"
Width="90" Height="30"
Content="Desktop"
FontSize="13" Foreground="White"/>
Hope this helps, cheers.
Edit: Updated to reflect path considerations for templatebinding in wpf as per OP's comments.
I'm having really trouble understanding templates and how to use them and re-use them across my App. I have defined two style templates in a resource dictionary, then in my page load them in the correct control and set the style to the resource in dictionary, but nothing showing in screen, nothing at all. I have the control working in another page but I am trying to make it re-usable, code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CustomListBox" TargetType="ListBox">
<Style.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Style>
<ScrollViewer x:Key="Scroller">
<ScrollViewer.VerticalScrollBarVisibility>
Auto
</ScrollViewer.VerticalScrollBarVisibility>
</ScrollViewer>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CustomExpander" TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<DockPanel>
<ToggleButton
DockPanel.Dock="Top"
Background="Teal"
HorizontalAlignment="Left"
Content="{TemplateBinding Content}"
Foreground="WhiteSmoke"
FontSize="12"
Name="Header"
Padding="1"
>
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock Text="{TemplateBinding Content}"/>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter
Content="{TemplateBinding Content}"
Name="ExpandSite"
Visibility="Collapsed"
DockPanel.Dock="Bottom"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Implementation:
<UserControl x:Class="Neotek.Contabilidad.UI.Views.AdminView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:Neotek.Contabilidad.UI.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Visual Resources/MenuDesplegableRD.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" Style="{StaticResource CustomListBox}" Background="Yellow" Width="200" Height="200">
<Expander Width="200" Height="200" Background="Violet"
Style="{StaticResource CustomExpander}">
<Expander.Header>
<TextBlock Text="Administrar Cuentas"
Foreground="White" />
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
<Expander Style="{StaticResource CustomExpander}">
<Expander.Header>
<TextBlock Text="Administrar Cuentas"
Foreground="White" />
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
</ListBox>
</Grid>
</UserControl>
I have this working:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ListBox.Resources>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Expander Background="OliveDrab">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="60" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Administrar Cuentas" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
<Expander Background="OrangeRed">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Rubros" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel Orientation="Vertical" >
<Label Margin="20,5,5,5" Foreground="white" Content="----------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="----------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="----------------"/>
</WrapPanel>
</Expander>
<Expander Background="Teal">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Subrubros" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="----------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="-------------------"/>
</WrapPanel>
</Expander>
</ListBox>
Any clues what's happening or what I am getting wrong with templates??
Change background of DockPanel, this will use Background property set in Expander in DockPanel. You have set it to Violet.
<DockPanel Background="{TemplateBinding Background}">
Change ToggleButton Content property to <ToggleButton Content="{TemplateBinding Header}".
This will show your Header content of Expander in ToggleButton. You have set it to 'Administrar Cuentas'.
Change control template of your Expander from
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock Text="{TemplateBinding Content}"/>
</ControlTemplate>
to
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="Yellow" BorderThickness="3" CornerRadius="5" Background="{TemplateBinding Background}" Height="24">
<ContentPresenter/>
</Border>
</ControlTemplate>
</ToggleButton.Template>
You are trying to put TextBlock of your Header content(set in XAML) inside TextBlock(template). Now, after change TextBlock of Header content will appear within border. Note here <ContentPresenter/> is pointing to
Header.
These changes are enough. I have also changed Horizontal properties of Expander like :
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
/////////// Changed ResourceDictionary //////////
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CustomListBox" TargetType="ListBox">
<Style.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Style>
<ScrollViewer x:Key="Scroller">
<ScrollViewer.VerticalScrollBarVisibility>
Auto
</ScrollViewer.VerticalScrollBarVisibility>
</ScrollViewer>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CustomExpander" TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<DockPanel Background="{TemplateBinding Background}">
<ToggleButton
Content="{TemplateBinding Header}"
DockPanel.Dock="Top"
Background="Teal"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Foreground="WhiteSmoke"
FontSize="12"
Name="Header"
Padding="1"
>
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="Yellow" BorderThickness="3" CornerRadius="5" Background="{TemplateBinding Background}" Height="24">
<ContentPresenter/>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter
Content="{TemplateBinding Content}"
Name="ExpandSite"
Visibility="Visible"
DockPanel.Dock="Bottom"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have touched only your ResourceDictionary, and added background to your second expander.
Output after modifying your styles only.
In my .xaml file these are my resources:
<DataTemplate DataType="{x:Type vm:KeyModel}">
<TextBlock DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" FontFamily="Verdana" FontSize="26" Margin="0" >
<Run Text="{Binding Content.Text, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
And here's the style:
<Style x:Key="RoundCorner" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="8" BorderBrush="#006AB6" BorderThickness="1" Name="border" Background="{TemplateBinding Background}">
<Grid x:Name="grid" >
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="18"/>
</Style>
And in code I have:
<Button Name="btn_Q" FontSize="8" Content="{Binding KB.Key_Q}" Grid.Column="1" Style="{DynamicResource RoundCorner}"/>
<Button Name="btn_A" Content="{Binding KB.Key_A}" Grid.Column="1" Style="{DynamicResource RoundCorner}"/>
But the FontSize for btn_Q doesn't get to be 8. How can I fix it? I need to make only btn_Q to have a fontsize of 8. All of my other buttons, like btn_A are fine with the style's fontsize.