Removing outer border of toggle button wpf - c#

So I have looked through numerous questions where people want to mess with borders of their buttons. I am using a toggle button (WPF) and it seems like there is an 'inner' border and an 'outer' border. I can manage to change the inner boarder to red, but I have no clue how to change the color of the outer border, or even get rid of it. I have gotten rid of the chrome button or whatever that comes with the aero theme, but I still cannot change this border. This is the picture of what I am getting for toggle buttons:
As you can see there is white in the borders. Here is my code for that style:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Button BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Foreground="White">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Button>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
</Trigger>
<Trigger Property="IsChecked" Value="true">
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am using it like this:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
But what I would like the buttons to look like is:
I achieved the above buttons by just overriding the default button style, but I can't seem to do it with the Toggle Button. I tried overriding Radio Button also, and I had the same problem. What am I missing? Can I somehow use the Button style instead of the toggle button style? I am just starting to learn Styles, so don't be to harsh! Appreciate all input though!

The Button in your controltemplate is creating the extra borders. If you replace Button with a Border you can style the togglebutton borders. Is there a reason you're using a Button? You can use triggers to provide the button behavior if needed. See below:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Name="Border" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" >
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource CheckedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

I have only tested it with Buttons, RadioButtons, and ToggleButtons, but the problem arises when trying to nest buttons withing a listbox. So I switched the code from:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
to:
<StackPanel Grid.Column="3" Grid.Row="2">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</StackPanel>
and I got the visual results I wanted (we will see if they work properly).

Related

WPF Override control background property

I'm kind of new to WPF and I'm not really sure how the whole thing works. I have three buttons below, which I would like to be individually coloured. I also want them to be transparent and have grey text when they are disabled.
I want them to retain the Background colour property assigned in MainWindow.xaml when they are enabled and be transparent when disabled.
I'm not sure how I would go about this. Does it involve templates, styles, binding converters? Any help would be greatly appreciated.
MainWindow.xaml
<Button Grid.Column="0" Content="Suspend" Style="{StaticResource BubbleButton}" IsEnabled="True" Background="Blue"/>
<Button Grid.Column="1" Content="Training Mode" Style="{StaticResource BubbleButton}" IsEnabled="True" Background="Orange"/>
<Button Grid.Column="2" Content="Exit Program" Style="{StaticResource BubbleButton}" Background="Red"/>
App.xaml
<Style x:Key="BubbleButton" TargetType="{x:Type Button}">
<!-- Triggers -->
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Trigger.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Gray"/>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
<!-- Style -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="10" Background="{TemplateBinding Background}" Name="Button" Margin="10,5,10,5">
<Grid>
<Border BorderThickness="1,0,1,1" BorderBrush="Black" CornerRadius="{Binding ElementName=Button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="2" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border BorderThickness="0,1,0,0" BorderBrush="White" Margin="2" Opacity="0.7" CornerRadius="{Binding ElementName=Button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="2" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<TextBlock TextWrapping="WrapWithOverflow" Text="{TemplateBinding Content}" FontWeight="Medium" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="20" />
</Style>
Enabled:
Disabled:
using ControlTemplate.Triggers and adding TargetName should make it work. do the same for TextBlock and Foreground (from what I see, the Setter in Style, not in Trigger should be White).
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Button" Property="Background" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>

Connecting The ComboBox Popup Border to Main ComboBox Border

I'm trying to match the Style of a ComboBox I'm creating to a design I have.
I'm unable to connect the Popup border to the Main Border that shows the selected ComboBox item.
I took this ComboBox Template from a site, changed some properties to match the design's style, things were coming along good until I realized I can't connect these 2 aforementioned borders. I'm not exactly sure how we could go about doing it.
I also thought about adding 2 Rows and making the ComboBox Popup Rowspawn but that didn't work either.
Creating a StackOverflow post as I ran out of ideas, any ideas are welcome.
Thank you in advance.
Edit: I was able to use VerticalOffset to move the Popup up, where I want it to be but I can't tuck it underneath the Border I create within the ToggleButton template. Panel.ZIndex usage didn't help either. Still working on a way to accomplish this task.
Design:
My ComboBox:
Here's the part I have an issue with (Along with other parts that I'll address myself later):
Here's my code:
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="4"
Background="#FFFFFF">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
Opacity="0.29"
BlurRadius="5"/>
</Border.Effect>
</Border>
<Border Grid.Column="0"
CornerRadius="4,0,0,4"
Margin="0,0,1,0"
Background="#FFFFFF"
BorderBrush="LightGray"
BorderThickness="0,0,1.7,0">
</Border>
<Canvas Width="30"
Height="30"
Grid.Column="1"
Margin="9,-18,0,0">
<Canvas.LayoutTransform>
<MatrixTransform Matrix="1,0,0,-1,0,0" />
</Canvas.LayoutTransform>
<Path Data="M131.6625 270.6375A21.1875 21.1875 0 0 0 168.4125 270.6375L296.98125 51.88125C305.55 37.29375 295.25625 18.75 278.60625 18.75H21.45C4.78125 18.75 -5.49375 37.3125 3.075 51.88125L131.6625 270.6375z"
Stroke="{x:Null}"
Fill="#707070"
Stretch="Uniform"
Width="10"
Height="10"
SnapsToDevicePixels="False"
UseLayoutRounding="False"
StrokeThickness="0"
StrokeStartLineCap="flat"
StrokeEndLineCap="flat"
StrokeLineJoin="miter"/>
</Canvas>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Foreground" Value="#707070"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="15,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="15,3,23,3"
Focusable="True"
Background="#FF3F3F3F"
Foreground="Green"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
Margin="15,15,15,15">
<Border
x:Name="DropDownBorder"
Background="White"
BorderThickness="0"
BorderBrush="#888888">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
Opacity="0.29"
BlurRadius="5"/>
</Border.Effect>
</Border>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
<!-- SimpleStyles: ComboBoxItem -->
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Foreground" Value="#707070"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter Margin="8,3,23,3"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

TextBox SelectionStart is always 0 with custom style

I have a TextBox input field with a custom style:
<TextBox Style="{StaticResource SettingsTextBoxHint}" KeyDown="textBoxInput_KeyDown" PreviewKeyDown="textBoxInput_PreviewKeyDown" Name="TextBoxInput" Text="{Binding TextBoxInput, Mode=TwoWay}" Tag="{lex:LocText TypeAMessageHere}" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" FontSize="14" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Margin="0,0,33,0"/>
To which I added the custom style:
<Style TargetType="{x:Type TextBox}" x:Key="SettingsTextBoxHint" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="White"
Padding="1,2,5,2"
BorderBrush="{StaticResource PrimaryColor}"
ToolTip="{TemplateBinding ToolTip}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
BorderBrush="Transparent"
TextWrapping="{TemplateBinding TextWrapping}"
Panel.ZIndex="2"
FontSize="12">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
CornerRadius="0">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<TextBox Margin="0,3,0,0" BorderThickness="0" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="{StaticResource RobotoRegularFont}" />
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="#cccccc"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=textSource}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The point of which is to make the TextBox transparent and to add hint functionality which text is set trough Tag.
Everything works exactly as I want. The problem I have is that I am writing a new functionality in which I need the position of cursor in the TextBox. But SelectionStart or CaretIndex always return 0 value. If I remove my style I get the correct value.
Can anyone tell me what I missed?
The problem is that you are using a TextBox within a TextBox. The user interacts with the inner text box, whose text, caret position, etc. are in no way related to the outer text box.
Let me clean up your style for you:
<Style x:Key="SettingsTextBoxHint"
TargetType="{x:Type TextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderBrush"
Value="{StaticResource PrimaryColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
<TextBlock x:Name="Hint"
Margin="3,1"
Text="{TemplateBinding Tag}"
FontStyle="Italic"
Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
Visibility="Hidden" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter TargetName="Hint" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To find the cursor position within the TextBox, you can use Mouse.GetPosition(your_text_box). To get the caret position within the text, use the CaretIndex property. Note, however, that CaretIndex is *not* a dependency property, so it does not raise change notifications. Thus, you cannot bind to it and expect the binding target to be updated.

How to underline textblock which is a child of a button when button is hovered

I have the following style
<Style x:Key="RoundedBtn" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Image x:Name="image" Source="{Binding ButtonImage, RelativeSource={RelativeSource AncestorType=Button}}" Margin="0,2,0,3" HorizontalAlignment="Left" Width="40" />
<Border BorderBrush="{x:Null}" Height="16" Margin="45,15,0,14" Width="123" HorizontalAlignment="Left">
<TextBlock x:Name="textBlock" Margin="-1" TextWrapping="Wrap" Text="{Binding ButtonText, RelativeSource={RelativeSource AncestorType=Button} }"
FontSize="13"
FontFamily="{DynamicResource Helvetica}" VerticalAlignment="Center" TextDecorations="{x:Null}">
</TextBlock>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#8da0aa"></Setter>
<Setter Property="Foreground" Value="#318EE4"></Setter>
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline">
<!--That Text decoration part doesnt work--></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I apply this style to my "usercontrol" (which is actually a button):
<Button x:Name="btn" x:Class="MyStock.MyButton"
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" Height="45" Width="183" Style="{DynamicResource RoundedBtn}" />
When I generate the project, the "MyButton" appears in my custom controls. But if I drag it on my form and test it, the Text Underline doesnt work.
But If i put a normal button on my form and then apply the RoundedBtn style, it works, why ?
By the way, what I am trying to achieve is to have a button that looks like the left menu buttons on this page
Use TargetName in the Setter:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
The whole style looks like this (I remove irrelevant part for readability)
<Style x:Key="RoundedBtn" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button">
<Grid>
<Border>
<TextBlock x:Name="textBlock" Margin="-1" TextWrapping="Wrap" Text="ABC"
FontSize="13" TextDecorations="{x:Null}">
</TextBlock>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Wpf Button Style is not applied

I have a window that has tow group boxes, each group box has 3 buttons, all of the buttons apply the 3 styles. the styles is:
<Style x:Key="SaveButtonStyle" TargetType="Button" >
<Setter Property="Content">
<Setter.Value>
<DockPanel>
<Image Source="/SalesSolution;component/Images/save.png" Stretch="UniformToFill" Height="40" Width="40" VerticalAlignment="Center" />
<Label Content="Save" HorizontalAlignment="Right" VerticalContentAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" FontSize="16" />
</DockPanel>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="UpdateButtonStyle" TargetType="Button" >
<Setter Property="Content">
<Setter.Value>
<DockPanel>
<Image Source="/SalesSolution;component/Images/Refresh_font_awesome.png" Stretch="UniformToFill" Height="40" Width="40" VerticalAlignment="Center" />
<Label Content="Update" HorizontalAlignment="Right" VerticalContentAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" FontSize="16" />
</DockPanel>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="DeleteButtonStyle" TargetType="Button" >
<Setter Property="Content">
<Setter.Value>
<DockPanel>
<Image Source="/SalesSolution;component/Images/delete.png" Stretch="UniformToFill" Height="40" Width="40" VerticalAlignment="Center" />
<Label Content="Delete" HorizontalAlignment="Right" VerticalContentAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" FontSize="16" />
</DockPanel>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="100"/>
</Style>
The buttons' XAML code:
//These three buttons do not applied the styles:
<Button HorizontalAlignment="Left" Name="buttonCompanySave" VerticalAlignment="Center" Click="buttonCompanySave_Click" Margin="188,215,0,323" Style="{StaticResource SaveButtonStyle}" />
<Button HorizontalAlignment="Left" Name="buttonCompaniesUpdate" VerticalAlignment="Center" Click="buttonCompanyUpdate_Click" Margin="188,274,0,264" Style="{StaticResource UpdateButtonStyle}" />
<Button HorizontalAlignment="Left" Name="buttonCompanyDelete" VerticalAlignment="Center" Click="buttonCompanyDelete_Click" Margin="188,333,0,205" Style="{StaticResource DeleteButtonStyle}" />
//These three buttons apply the styles:
<Button HorizontalAlignment="Left" Name="buttonItemSave" VerticalAlignment="Bottom" Click="buttonItemSave_Click" Style="{StaticResource SaveButtonStyle}" />
<Button HorizontalAlignment="Center" Name="buttonItemsUpdate" VerticalAlignment="Bottom" Click="buttonItemsUpdate_Click" Style="{StaticResource UpdateButtonStyle}" />
<Button HorizontalAlignment="Right" Name="buttonItemDelete" VerticalAlignment="Bottom" Click="buttonItemDelete_Click" Style="{StaticResource DeleteButtonStyle}" />
The strange problem is: if I move the blank buttons(buttonCompanySave,buttonCompaniesUpdate,buttonCompanyDelete) to the other group box, they apply the styles !. I try to figure out this problem but I don't find the solution, I even create new group boxes and buttons.
It happens cause your style changes Content property and when you set new Content value, then default style of Button is applied which does not have any Image and Label.
Instead of this you should create ContentPresenter for setting Content property dynamically and create your Image near the ContentPresenter. In addition, to exclude multiple Style's you can use DataTrigger to change Source of Image. Please, see the following example:
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="#ffffff"/>
<Setter Property="BorderBrush" Value="#cccccc"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="#333333"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="16,3,16,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<StackPanel>
<TextBlock x:Name="txtBlck" Text="Update"/>
<Image x:Name="img">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Content, ElementName=Presenter}" Value="Update">
<Setter Property="Source" Value="/SalesSolution;component/Images/update.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content, ElementName=Presenter}" Value="Save">
<Setter Property="Source" Value="/SalesSolution;component/Images/save.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content, ElementName=Presenter}" Value="Delete">
<Setter Property="Source" Value="/SalesSolution;component/Images/delete.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter Name="Presenter" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#333333" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#dddddd" />
<Setter Property="BorderBrush" Value="#cccccc" />
<Setter Property="Foreground" Value="#333333" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#1ba1e2" />
<Setter Property="BorderBrush" Value="#1ba1e2"/>
<Setter Property="Foreground" Value="#ffffff"/>
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter TargetName="Chrome" Property="BorderBrush" Value="#1ba1e2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
#StepUp: I Updated your code then it is working fine now:
<Image x:Name="img" Stretch="Uniform" StretchDirection="Both">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=txtBlck}" Value="Update">
<Setter Property="Source" Value="/SalesSolution;component/Images/update.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text, ElementName=txtBlck}" Value="Save">
<Setter Property="Source" Value="/SalesSolution;component/Images/save.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text, ElementName=txtBlck}" Value="Delete">
<Setter Property="Source" Value="/SalesSolution;component/Images/delete.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
If you have not: Move your button styles into App.xaml.
Or at least into the resource section of the window:
<Window ... >
<Window.Resources>
<!--Your button styles:-->
</Window.Resources>
</Window>

Categories