WPF: Get Tag Property from ResourceDictionary - wpf

I'm assigning a text to Tag property of the Button but how can I use it from ResourceDictionary.
My Button:
<Button Style="{StaticResource ControlBarButton}" Tag="-"/>
I want to use Tag property from content of the button
My Resource Dictionary:
<Style TargetType="Button"
x:Key="ControlBarButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Width="35"
Content="I WANT TO USE `Tag` HERE">
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Use a TemplateBinding in the template:
<Style TargetType="Button" x:Key="ControlBarButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Width="35"
Content="{TemplateBinding Tag}">
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

WPF: How to use BasedOn Style

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.

Syling child elements

I have style for Button
<Style x:Key="menu_button" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Label Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
it must be applied to the buttons
<StackPanel>
<Button Content="Создать тест" Style="{DynamicResource menu_button}"/>
<Button Content="Тесты" Style="{DynamicResource menu_button}"/>
</StackPanel>
How to make that do not prescribe style to each button, and enter it in the StackPanel. After all, it will be very tiring
In case you can move the style and you do not use the style at another place you can do it this way:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Label Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Button Content="Создать тест"/>
<Button Content="Тесты"/>
</StackPanel>

Accessing elements parent style XAML Silverlight

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

Binding to Control which applied the Style/Template

I want to (re-)template a Control, for example a ComboBox.
XAML:
<ComboBox Style="{StaticResource MyComboBoxStyle}" ... >
<!-- ... -->
</ComboBox>
In the ControlTemplate I want to have a Button.
ResourceDictionary:
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<!-- ... -->
<Button Command="{TemplateBinding Tag}" CommandParameter="{Binding ???}" />
<!-- ... -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But I want to set the CommandParameter to the Control which applied the Template (in this example the ComboBox).
How can I solve this?
Ok, i found the right solution.
I have set the Binding to Binding RelativeSource={RelativeSource TemplatedParent}
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<!-- ... -->
<Button Command="{TemplateBinding Tag}" CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
<!-- ... -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to configure Contentpresenter in nested ControlTemplate?

I have the following code:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter .../>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
I need button inside template for binding possibility. The nested template defines the appearance.
The question: <ListBoxItem Content="Start"/> does not work with code above. I need something like root Contentpresenter that refers to Contentpresenter inside button template. How can I do this?
Thanks in advance!
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=Content}"/>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>

Resources