Basically, i have a checkbox which has the IsChecked property binded in the viewmodel. This property is then evaluated inside a datatrigger to decide the color of a progress bar. The Progress bar itself, is styled with the code that i'm going to present.
Now, this code work:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{Binding}"/>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
while the following not:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Can you tell me what is missing or what is wrong in the second xaml? (don't mind to the border part)
I think you have those backwards: the second example works, while the first does not.
The first example doesn't work because the Rectangle.Fill binding doesn't make sense. You're binding the Fill to whatever ProgressBar.DataContext is. Change the Rectangle definition to:
<Rectangle x:Name="PART_Indicator"
HorizontalAlignment="Left"
Fill="{TemplateBinding Background}" />
{TemplateBinding XYZ} is a short form of {Binding Path=XYZ, RelativeSource={RelativeSource TemplatedParent}. It means "bind to property XYZ on the control to which this template is applied". In this case, the template is applied to a ProgressBar, so we are binding Rectangle.Fill to the progress bar's Background. When your Setters update the background, the rectangle gets updated too.
Related
I want to create a table on wpf that each column header has a round corner this is what i got so far:
as you can see, i have the desired outcome with a little un desired outcome.
the undesired out come is that the all data grid header itself (not the columns) is getting the same border, i need to make it transparent, how can i do that?
this is the part of the style:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="SeparatorBrush" Value="Transparent"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding }"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
for some reasons, DataGrid has a blank DataGridColumnHeader in its template. that blank columns doesn't have DataContext value (null). So change border brush to transparent in a DataTrigger:
<ControlTemplate>
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" >
<TextBlock Text="{Binding}"/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter Property="BorderBrush" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
</ControlTemplate>
improved version, which uses ContentPresenter in header template and test Content in a trigger
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" >
<ContentPresenter/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}">
<Setter Property="BorderBrush" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
</ControlTemplate>
header is not necessary a text, e.g.:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}">
<DataGridTextColumn.Header>
<Border Background="Cyan">
<TextBlock Text="NAME" Margin="5"/>
</Border>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
I'm working on a custom TabControl for my C#-WPF-application. Basically, everything I want works just fine. Except for one litte thing that really annoys me: The first TabItem of the TabControl is indentet 2 pixels and therefore won't align with the left border of the TabControl. Unfortunately I can't yet post pictures, so I hope you guys get what I mean...
So, is there any possibility to get the first TabItem aligned with its TabControl? Maybe by somehow setting its position?
Here's the entire XAML-code:
<UserControl x:Class="DocumentationOfXmlInterfaces.CentralTabControl"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl
Name="MyTabcontrol"
BorderBrush="Navy"
BorderThickness="2"
ItemsSource="{Binding}"
SelectionChanged="MyTabcontrol_SelectionChanged"
>
<TabControl.Resources>
<Style TargetType="TabPanel">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
ClipToBounds="True"
>
<Border
x:Name="MyBorder"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Navy"
BorderThickness="1"
>
<DockPanel
Name="MyDockpanel_Content"
>
<ContentPresenter
x:Name="MyContentPresenter"
HorizontalAlignment="Center"
Content="{TemplateBinding Content}"
/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="RoyalBlue"
/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="White"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="TabHeader" DataType="TabItem">
<DockPanel>
<Button
Name="MyButton_CloseTab"
DockPanel.Dock="Right"
Margin="10,1,1,0"
Click="MyButton_Click"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}"
>
<Image Name="MyImage_Button" Source="Icons/Close.png" Height="12" Width="12"/>
</Button>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}"/>
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Hidden"
/>
<Setter
TargetName="MyImage_Button"
Property="Source"
Value="Icons/Close2.png"
/>
<Setter
TargetName="MyImage_Button"
Property="Height"
Value="12"
/>
<Setter
TargetName="MyImage_Button"
Property="Width"
Value="12"
/>
</DataTrigger>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsMouseOver}"
Value="True"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Visible"
/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border
x:Name="MyBorder"
BorderBrush="Navy"
BorderThickness="1,1,1,0"
>
<Grid Name="Panel">
<ContentPresenter
x:Name="ContentSite"
ContentSource="Header"
Margin="5,0,0,0"
/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="Navy"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="RoyalBlue"/>
<Setter TargetName="MyBorder" Property="BorderBrush" Value="RoyalBlue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyBorder" Property="BorderBrush" Value="Navy"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid">
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
</Style>
</TabControl.Resources>
</TabControl>
I'd really appreciate your help!
Thanks! :)
Your problem here is that the headers TabPanel inside the TabControl template has its Margin set explicitly, and your Style won't be able to override it.
You may need to modify the whole TabControl's Template to change the value of that Margin.
So maybe it'd be easier to just do the negative margin trick :P
In the same mindset as this answer (Change GroupBox Header location), you could have a negative left margin on your tab item. Like this: Margin="-2,0,0,0"
my idea is to change appearance of ListboxItem when MouseOver or Button is clicked etc.
<ListBox Name="listbox"
Height="250"
Grid.Row="4"
Grid.ColumnSpan="5"
HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Template"
Value="{StaticResource control_mouseover}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Template"
Value="{StaticResource control_not_mouseover}" />
</Trigger>
<DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}"
Value="True">
<Setter Property="Template"
Value="{StaticResource control_mouseover}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Only for events IsMouseOver it works but DataTrigger does not seem to work
Do you happen to know why?
<ControlTemplate x:Key="control_not_mouseover"
TargetType="ListBoxItem">
<Border BorderBrush="Transparent">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource not_mouseover}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
<ControlTemplate x:Key="control_mouseover"
TargetType="ListBoxItem">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource mouseover}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" />
</ControlTemplate>
<StackPanel>
<Grid Name="grid"
Height="240">
<Button Name="Artykuły"
Grid.Column="0"
Content="{Binding Path=liczba_wpisow, Converter={StaticResource wpisy_converter}}" /> [...]
</Grid>
<Listbox... />
</StackPanel>
I see a number of problems with your code. The first is that you don't need to add a Trigger for both true and false conditions. Instead, you should do this:
<ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</Trigger>
<DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
However, this should not cause an actual error.
The second problem is that the ElementName property show be set to the actual name of the relevant control and not to the type and name:
<DataTrigger Binding="{Binding ElementName=Artykuły, Path=IsPressed}" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</DataTrigger>
UPDATE >>>
To permanently apply your Template rather than just having it when the Button is pressed, just remove the DataTrigger and move the Setter out of the Triggers collection:
<ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Unfortunately, your Setter values clashed, so I had to swap them over to make it work this way, but I believe that you can re-arrange it as you see fit.
Binding="{Binding ElementName=grid.Artykuły
<Button Name="Artykuły"
-> ElementName does not match your element's Name.
Should be :
Binding="{Binding ElementName=Artykuły
My original datagrid does have a few columns wherein the bound value is bool.[By default this would show up as check boxes]
I have defined a cell template and could create
I would like to use a common datagrid controltemplate for this, like the one defined below.
However it doews not bring in the binding value - it shows up blank.
Could someone help spot me on what I am doing wrong?
<Style x:Key="dgCellBool" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Ellipse>
<Ellipse.Height>10</Ellipse.Height>
<Ellipse.Width>10</Ellipse.Width>
<Ellipse.Style>
<Style TargetType="Ellipse">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Binding}" Value="True">
<Setter Property="Fill" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Binding}" Value="False">
<Setter Property="Fill" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks
Rajesh
You are trying to bind Binding property of DataGridCell but DataGridCell dont have any Binding property. Yoy should set Path=Column.Binding. DataGridCell has Column property which further has Binding Property.
Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Column.Binding}"
I hope this will help.
You need to provide a ContentPresenter to present the content and make sure you add the Border that you will lose from the original Template:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
UPDATE >>>
If you want your Ellipse instead of a Border, just add it back in with a Grid... Ellipse objects cannot have any content:
<Style x:Key="dgCellBool" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Ellipse Height="10" Width="10">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={
RelativeSource TemplatedParent}, Path=Binding}" Value="False">
<Setter Property="Fill" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The EditCommandButton style defined below is showing odd behavior; it only shows for the last instance defined (next to the Avatar label below).
I tried making the style x:Shared="true" and using DynamicResource but with the same result.
I do eventually want the button to invisible until request, which is why you see a trigger for that. But until I figure this out I just have the default visibility at visible.
Can someone explain this behavior and offer a fix?
Cheers,
Berryl
Design View
Runtime View
Button Style
<Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="theBorder" Background="Transparent" CornerRadius="4">
<ContentPresenter x:Name="theContent" Visibility="Visible" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
<Setter TargetName="theBorder" Property="Background" Value="Orange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
</Style>
Usage
<DataTemplate x:Key="PersonInfoEditingControlTemplate">
<Grid>
...
<Label Grid.Column="0" Grid.Row="0" ... />
<Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="0"/>
<TextBlock .../>
<Label Grid.Column="0" Grid.Row="1" ... />
<Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="1"/>
<TextBlock .../>
<TextBlock Grid.Column="0" Grid.Row="2" .../>
<Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="2"/>
<Image Grid.Column="2" Grid.Row="2" ... />
</Grid>
</DataTemplate>
EDIT for Rachel
Look Ma, no triggers! Only the last button shows the arrow though...
<Style x:Key="TestCommandButtonStyle" TargetType="{x:Type Button}" >
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
</Setter.Value>
</Setter>
<Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
</Style>
the FIX
<Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
<Setter Property="Content" Value="a" />
<Setter Property="Foreground" Value="Navy" />
<Setter Property="FontFamily" Value="Wingdings 3" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="Auto" />
<Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="theBorder" CornerRadius="4">
<ContentPresenter x:Name="theContent" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="theContent" Property="Visibility" Value="Hidden"/>
<Setter TargetName="theBorder" Property="Background" Value="Transparent"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
<Setter TargetName="theBorder" Property="Background" Value="Orange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The style as originally written actually had two problems, both fixed by the style above. (by fixed I mean it works as intended, not that it is the 'right' way to do it!):
DP Precedence - this is what Rachel's answer is addressing although her answer. But the only effective fix I found is to set visibility using two triggers for IsMouseOver as shown.
Only the last item in the Grid was showing any content! - this one makes no sense to me, but moving the properties previously in the TextBlock content to Setters on the style fixes that.
Dependencey properties defined in the <Tag> have a higher precedence than items defined in triggers, so will always overwrite them.
For example, in this case the button's Visibility will always be Collapsed regardless of what the trigger is, because the property is defined in the <Button> tag
<Button Visibility="Collapsed">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Property="{Binding SomeValue}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
To make this trigger work, move the Visibility property to a Style Setter, which has a lower precedence than a Style Trigger, so triggered values will overwrite it
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Property="{Binding SomeValue}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
See MSDN's Dependency Property Precedence List for more information
Edit
As for your second problem about the Content only showing up once, I suspect it is because you have the Content bound in your style, and not the ContentTemplate.
WPF is creating a single instance of the TextBlock arrow, and a control can only have one parent, so after the style is applied, so only one Button can contain the arrow TextBlock
The fix is to use the ContentTemplate property instead of the Content property.
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
</DataTemplate>
</Setter.Value>
</Setter>
Honestly, I'm surprised it didn't give you an error about Specified element is already the logical child of another element. That is usually what happens in these kind of cases (see my post here for more details)