How to style WPF tooltip like a speech bubble? - wpf

I want to shape my WPF tooltip like the image below:
How do I achieve this?

Use this Code:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Window.Resources>
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<ed:Callout Name="Border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinWidth="100"
MinHeight="30"
Margin="0,0,0,50"
AnchorPoint="0,1.5"
Background="{StaticResource LightBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1"
CalloutStyle="RoundedRectangle"
Fill="#FFF4F4F5"
FontSize="14.667"
Stroke="Black">
<ContentPresenter Margin="4"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</ed:Callout>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button ToolTip="Hello" />
</Grid>
this is the begining, now you have to play with it... enjoy!

Related

Problem with icon in TabHeader - Icon path is correct but icon will not load

I need to show Icons in the tabitem header.
The challenge is to load the text and the icon path from the "Window.Resource"
Every tab item should use the same style resource and load the assigned array data.
My Problem is, the picture for the path will not load.
Where is my error or what I have to do in an other way?
<Window x:Class="Wpf_TabItem_Image.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip"
UseLayoutRounding="True">
<Window.Resources>
<SolidColorBrush x:Key="Color_red" Color="Red" />
<SolidColorBrush x:Key="Color_white" Color="White" />
<SolidColorBrush x:Key="Color_black" Color="Black" />
<SolidColorBrush x:Key="Color_darkgrey" Color="DarkGray" />
<Style x:Key="TabControl_reference" TargetType="{x:Type TabControl}">
<Setter Property="TabStripPlacement" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TabPanel Grid.Row="0"
Grid.Column="0"
Margin="0"
Panel.ZIndex="0"
IsItemsHost="True"
Background="{StaticResource Color_white}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TabItem_reference" TargetType="TabItem">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid>
<Border x:Name="TabItemBorder" CornerRadius="0" BorderThickness="0" BorderBrush="Transparent">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" ContentSource="Header" />
</Border>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,0,10,0">
<Image Source="{Binding [4]}" /> <!-- Why isn't the image shown? -->
<Image Source="{Binding [3]}" /> <!-- Why isn't the image shown? -->
<Image Source="{Binding [1]}" /> <!-- Why isn't the image shown? -->
<Image Source="{Binding [0]}" /> <!-- Why isn't the image shown? -->
<TextBlock Text="{Binding [2]}"/> <!-- But text is shown... -->
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="{StaticResource Color_red}"/>
<Setter TargetName="TabItemBorder" Property="Background" Value="{StaticResource Color_black}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="{StaticResource Color_white}" />
<Setter TargetName="TabItemBorder" Property="Background" Value="{StaticResource Color_red}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<x:Array x:Key="TabItemHeaderContext" Type="{x:Type sys:String}">
<sys:String>/Image/info_red_48dp.png</sys:String>
<sys:String>~\..\Image\info_red_48dp.png</sys:String>
<sys:String>[ ? ] ReferencedText</sys:String>
<sys:String>/Wpf_TabItem_Image;component/Image/info_red_48dp.png</sys:String>
<sys:String>pack://application:,,,/Wpf_TabItem_Image;component/Image/info_red_48dp.png</sys:String>
</x:Array>
<x:Array x:Key="TabItemHeaderContext2" Type="{x:Type sys:String}">
<sys:String>/Image/hub_red_48dp.png</sys:String>
<sys:String>~\..\Image\hub_red_48dp.png</sys:String>
<sys:String>[ ? ] AnOtherReferencedText</sys:String>
<sys:String>/Wpf_TabItem_Image;component/Image/hub_red_48dp.png</sys:String>
<sys:String>pack://application:,,,/Wpf_TabItem_Image;component/Image/hub_red_48dp.png</sys:String>
</x:Array>
</Window.Resources>
<Grid>
<TabControl Style="{StaticResource TabControl_reference}">
<TabItem Header="No Reference" />
<TabItem Style="{StaticResource TabItem_reference}" DataContext="{StaticResource TabItemHeaderContext}">
<Grid>
</Grid>
</TabItem>
<TabItem Style="{StaticResource TabItem_reference}" DataContext="{StaticResource TabItemHeaderContext2}" >
<Grid>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>

Change Style of a child element in a CustomControl

I have a CustomTextBox as follows:
<TextBox x:Class="StackOverflow.CustomUserControl.CustomTextBoxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="MainTextBox"
mc:Ignorable="d">
<TextBox.Template>
<ControlTemplate>
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
Margin="0,0,0,5"
Panel.ZIndex="1" />
<Border CornerRadius="2"
Name="BorderToChange"
BorderThickness="0,0,0,3.7"/>
<TextBlock Text="{Binding ElementName=MainTextBox, Path=HintText}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground"
Value="Transparent" />
<Setter Property="Margin"
Value="0,0,0,3" />
<Setter Property="VerticalAlignment"
Value="Bottom" />
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</ControlTemplate>
</TextBox.Template>
I use this CustomTextBox as follows:
<customUserControl:CustomTextBoxView Width="50"
Height="50"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Text="{Binding Mode=TwoWay, Path=Period, UpdateSourceTrigger=PropertyChanged}"/>
Is there a way I can change the property BorderThickness of the Border element named "BorderToChange" inside the ControlTemplate of my CustomTextBox when using it? I have try the following, but it didn't work:
<customUserControl:CustomTextBoxView Width="50"
Height="50"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
FontSize="35"
Text="{Binding Mode=TwoWay, Path=Period, UpdateSourceTrigger=PropertyChanged}">
<customUserControl:CustomTextBoxView.Resources>
<Style TargetType="{x:Type customUserControl:CustomTextBoxView}">
<Style.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="10"></Setter>
</Style>
</Style.Resources>
</Style>
</customUserControl:CustomTextBoxView.Resources>
</customUserControl:CustomTextBoxView>
Use a {TemplateBinding} in the template:
<Border CornerRadius="2" Name="BorderToChange" BorderThickness="{TemplateBinding BorderThickness}"/>
...and specify a default value:
<TextBox x:Class="..." BorderThickness="0,0,0,3.7"> ...
You can then simply set the BorderThickness property of the control to override the default value:
<customUserControl:CustomTextBoxView ... BorderThickness="1" ... />

How to customize the style of CheckBox in WPF

I'm just begin study WPF, so I'm unfamiliar with style and template.
I want to customize a CheckBox with a Image and two Labels like this:
How can I do?
.xaml
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<CheckBox Width="150"
Height="40"
Margin="4"
Padding="4,0,0,0">
<Grid Background="#FFEEEEEE"
Width="130"
MaxWidth="Infinity">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Margin="5"
Source="/WpfApplication4;component/Images/LargeIcon.png" />
<Label Grid.Row="0"
Grid.Column="1"
Padding="0">
Label1
</Label>
<Label Grid.Row="1"
Grid.Column="1"
Padding="0">
Label2
</Label>
</Grid>
</CheckBox>
</StackPanel>
</Window>
Edit:
.xaml
<Application x:Class="WpfApplication4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyCheckBox"
TargetType="{x:Type CheckBox}">
<Setter Property="Width" Value="150"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Padding" Value="4,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel Background="#FFEEEEEE"
Height="34"
Width="130">
<Image DockPanel.Dock="Left"
Source="/WpfApplication4;component/Images/LargeIcon.png"
Margin="5" />
<TextBlock DockPanel.Dock="Top" Text="Label1" />
<TextBlock DockPanel.Dock="Top" Text="Label2" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
used in .xaml
<CheckBox Style="{StaticResource ResourceKey=MyCheckBox}" />
Something be presented, but the small grid is disappeared, like this:
How can I do?
The DockPanel may be the best option for this layout
Example:
<CheckBox>
<DockPanel Height="34">
<Image DockPanel.Dock="Left" Source="/WpfApplication4;component/Images/LargeIcon.png" Margin="2" />
<TextBlock DockPanel.Dock="Top" Text="Label1" />
<TextBlock DockPanel.Dock="Top" Text="Label2" />
</DockPanel>
</CheckBox>
Edit:
It looks like you still want to use the default Checkbox Template but just override the Content in your Style.
Example:
<Style x:Key="MyCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Width" Value="150"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Padding" Value="4,0,0,0"/>
<Setter Property="Content">
<Setter.Value>
<DockPanel Background="#FFEEEEEE" Width="130" MaxWidth="Infinity">
<Image DockPanel.Dock="Left" Source="Capture.png" Margin="5" />
<TextBlock DockPanel.Dock="Top" Text="Label1" />
<TextBlock DockPanel.Dock="Top" Text="Label2" />
</DockPanel>
</Setter.Value>
</Setter>
</Style>
Result:

Understanding how styling and templating work in Silverlight

I'm trying to understand how styles works in silverlight, this is what I've done :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="test.png" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100 />
</StackPanel>
The text and the image are displayed correctly, note that test.png is a resource file at the root of my projet.
First thing I don't understand : why is my image correctly displayed at runtime, but not at design in visual studio ?
Then, I would like to use a databinded value in my style, so I use :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{Binding MyUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" />
</StackPanel>
Ok, it's working, my viewmodel exposes an Uri with the test.png as relative.
What I would like to do now is to use the button with many images, so it could have been great to be able to do something like this :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding TheUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" TheUrl="{Binding MyUrl}" />
</StackPanel>
but the property TheUrl of course doesn't exists in the button.
I don't want to create my own control, the purpose is to understand styles.
How can I do this ?
Thanks in advance for any help.
Best regards
you are correct in your observation that button does not have a TheUrl property. You have to options here. One is to use the Tag property of Button:
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding Tag}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" Tag="{Binding MyUrl}" />
</StackPanel>
As an aside, I would not bind to the Width / Height properties, these may not be set explicitly. Instead, bind to ActualHeight and ActualWidth which you can guarantee will always be set.
Tag is a property of type object which can be used for general extensibility. The other, more elegant option is to define an attached property. See the tutorial in the following blog post:
http://www.hardcodet.net/2009/01/create-wpf-image-button-through-attached-properties

Parameterized style/template in WPF?

If I have two 200 lines long control templates which differ only in a few words (a few colors), how can I make the xaml reusable ? That is, to don't have to copy-paste the template and change 3 words in 200 lines.
Here is a simplified example. The only difference between the two styles is the border color. So can I somehow define a ButtonStyle, with a parameterized color, and inherit BlackButtonStyle and GrayButtonStyle from it, and specify only that color in BlackButtonStyle and GrayButtonStyle ?
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Black" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GrayButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Gray" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
Here is the code based on the 2 answers. Only a style needs to be set on the control, but unfortunately it still messes up the Tag of the control:
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border"
BorderBrush="Black"
BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Gray">
<Setter TargetName="border"
Property="BorderBrush"
Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlackButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}"/>
<Style x:Key="GrayButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}">
<Setter Property="Tag" Value="Gray"/>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
While Charlie's right about his example, for your specific case I'd just use the BorderThickness and BorderBrush properties that a button already exposes: you can use {TemplateBinding BorderBrush} instead of creating your own property.
Edit: sample xaml... note that my style defaults the color & thickness, but these could be overridden inline...
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Page.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="Black"/>
<SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="3" />
<Setter Property="BorderBrush" Value="{StaticResource BlackBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderColor="{TemplateBinding BorderThickness}">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Black Button" BorderBrush="{StaticResource BlackBrush}"
Style="{StaticResource CustomButtonStyle}"/>
<Button Content="Gray Button" BorderBrush="{StaticResource GrayBrush}"
Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
The right way to go about this is usually to create a DependencyProperty on the class that can hold the parametrized data, and then bind to that property in your template. For the sake of creating a quick example, I'm going to use the Button.Tag property, which works perfectly well for storing something as simple as a brush:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Page.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="Black"/>
<SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding Tag}" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Black Button" Tag="{StaticResource BlackBrush}"
Style="{StaticResource CustomButtonStyle}"/>
<Button Content="Gray Button" Tag="{StaticResource GrayBrush}"
Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
Have a look at this solution, it solves the exact issue you're having.

Resources