MouseOver style trigger won't change background - wpf

New to WPF, coming from a web background.
My style trigger won't change button background. Style XAML:
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="GhostWhite" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#F48230"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Button XAML (nothing relevant in Window or Grid attributes):
<Window...>
<Grid...>
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Name="btnEdit" Cursor="Hand" Content="Edit Settings..." HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Margin="0,0,5,0" Click="btnEdit_Click"/>
<Button Name="btnExit" Cursor="Hand" Content="Exit" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Margin="5,0,0,0" Click="btnExit_Click" />
</StackPanel>
</Grid>
</Window>
The buttons do pick up the background style in the resources section, but not the trigger - mouseover results in default behaviour.
Supplementary question: Is there a way I can debug this? I looked in Live Visual Tree but couldn't figure out how to get the info I need.

WPF Controls have a Template property of type ControlTemplate. This property tells WPF how to draw the control on the screen. A WPF Button uses Windows Chrome in it's ControlTemplate which uses user selected system colors to allow for consistency between different applications. Leveraging the magic of WPF and XAML, you can create your own ControlTemplate to make the button look any way you see fit.
Create a style with a key so you can choose which buttons use the template:
<Window.Resources>
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="GhostWhite" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<!-- a simple square button -->
<Border Name="wrapper"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="{TemplateBinding Margin}"
Background="#01000000">
<!-- notice the wrapper has a background that is NEAR transparent. This is important. It'll ensure the button raises the click event -->
<Border Name=inner
Background="{TemplateBinding Background}">
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFF48230"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" Value="#FF99501B"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
And then to use the template on a button:
<Window...>
<Grid...>
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Style="{StaticResource MyButtonStyle}" Name="btnEdit" Cursor="Hand" Content="Edit Settings..." HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Margin="0,0,5,0" Click="btnEdit_Click"/>
<Button Style="{StaticResource MyButtonStyle}" Name="btnExit" Cursor="Hand" Content="Exit" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Margin="5,0,0,0" Click="btnExit_Click" />
</StackPanel>
</Grid>
</Window>

Related

XAML - Cannot add border thickness to button when style is applied

I am trying to add a border thickness to my first navigation button. Normally, you can easily add a BorderThickness to a button but when I add my own style it hides the BorderThickness and BorderBrush. I added a BorderThickness to the style (0,0,0,1) but am not able to have a border thickness of (0,1,0,0) to the first initial button. Any ideas?
<UserControl.Resources>
<Style x:Key="navButtStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border BorderThickness="0,0,0,1" BorderBrush="Black"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Button Style="{StaticResource navButtStyle}"
x:Name="navButton1"
Grid.Row="1"
Content="TR"
Background="#33333D"
FontFamily="Roboto"
FontSize="65"
FontWeight="Bold"
Foreground="White"
BorderBrush="Black"
BorderThickness="0,1,0,0"
HorizontalContentAlignment="Center"
ToolTip="navButton0"
Click="navButton1_Click"
/>
<Button Style="{StaticResource navButtStyle}" x:Name="navButton2" Grid.Row="2" Background="#33333D" ToolTip="navButton2">
<Grid>
<TextBlock Text="󰂯" Padding="30,30,0,0" FontSize="56" FontFamily="Material Design Icons Desktop" Foreground="White"/>
<TextBlock Text="󰖩" Padding="0,0,30,30" FontSize="56" FontFamily="Material Design Icons Desktop" Foreground="White"/>
</Grid>
</Button>
<Button Style="{StaticResource navButtStyle}" x:Name="navButton3" Grid.Row="3" Content="SL" Background="#33333D" FontFamily="Roboto" FontSize="65" FontWeight="Bold" Foreground="White" HorizontalContentAlignment="Center" ToolTip="navButton3" />
Navigation Buttons
property value hardcoded in Template cannot be easily changed from outside. use TemplateBindings instead:
<Style x:Key="navButtStyle" TargetType="Button">
<Setter Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Modify a child control from trigger or better way to change their foreground?

I have a listbox with a template, inside the listboxitem I have 2 textblock.
My goal is to change the foreground of those 2 textblock when the listboxitem is:
Hovered(Mouse over)
Selected
My ItemTemplate currently removes the highlight when u hover over items, that works as expected.
I know I can get the IsSelected and IsMouseOver events, for example:
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="White"/>
<!-- I have no idea how to access the textblock child of the listboxitem to change it -->
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<!-- I have no idea how to access the textblock child of the listboxitem to change it -->
</Trigger>
But I could not figure out how to modify the TextBlock inside, I've tried using acestor and a whole different ways none worked(as in they had no effect).
Here is what my View looks like:
<UserControl x:Class="Shex.Views.SideBarView"
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:local="clr-namespace:Shex.Views"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:shex="clr-namespace:Shex"
mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="260"
Background="#403f42" Padding="0" BorderThickness="0" Margin="0">
<UserControl.Resources>
<Style x:Key="MenuContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0" Background="{TemplateBinding Background}"
Padding="0" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Margin="0">
<ListBox ItemsSource="{Binding MenuItems}" SelectionMode="Single" SelectedItem="{Binding SelectedMenuItem}" SelectionChanged="{s:Action ChangeView}"
BorderThickness="0" Padding="0" Margin="0 10 0 0" Background="#403f42" ItemContainerStyle="{DynamicResource MenuContainerStyle}" SnapsToDevicePixels="true">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="60" Orientation="Horizontal" SnapsToDevicePixels="true">
<TextBlock Text="{Binding Image}" FontFamily="/Shex;component/Fonts/Font Awesome 5 Free-Solid-900.otf#Font Awesome 5 Free Solid" Foreground="#cfced1" FontSize="20" Margin="10 6 0 0" Width="30" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Name}" Foreground="#cfced1" FontSize="20" Margin="10 6 0 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
You should add the trigger(s) to the ItemTemplate, e.g.:
<DataTemplate>
<StackPanel ...>
<TextBlock x:Name="tb1" ... />
<TextBlock x:Name="tb2" ... />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="True">
<Setter TargetName="tb1" Property="Foreground" Value="Blue" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
A ListBoxItem style cannot set properties of some individual TextBlock or any other control that is defined in the ItemTemplate.

Custom Control Styling/Triggers

I'm trying to make a custom control that consists of several buttons and a couple labels, but the buttons are supposed to be invisible, showing only the content within them. I can get rid of the border, background, etc by setting them to Transparent. But whenever I MouseOver them the default windows hover effect shows the whole button again. I've tried numerous guides on custom controls, but ultimately cannot figure out how to override this. Basically my questions boil down to, how much of this can be placed in the generic.xaml file, what organization do I have to use within that file, and are there any other places that these styling should go instead? I do realize this is a very basic question, but it's just driving me nuts not being able to figure out the specific answer. Thanks!
Current xaml:
<Style TargetType="{x:Type local:TimePicker}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TimePicker}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}">
<StackPanel Orientation="Horizontal">
<StackPanel x:Name="PART_Root"
Orientation="Horizontal"
HorizontalAlignment="Center">
<ToggleButton x:Name="PART_HourButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Height="{Binding ElementName=PART_IncDecPanel, Path=ActualHeight}"
Width="{Binding ElementName=PART_HourButton, Path=ActualHeight}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Hour}">
<ToggleButton.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</ToggleButton.Triggers>
</ToggleButton>
<Label x:Name="PART_HourMinSeparator"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Content=":" />
<ToggleButton x:Name="PART_MinButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Height="{Binding ElementName=PART_HourButton, Path=ActualHeight}"
Width="{Binding ElementName=PART_HourButton, Path=ActualWidth}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Minute}" />
<StackPanel x:Name="PART_IncDecPanel" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="PART_IncreaseTime"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Margin="0"
Padding="0"
Width="22"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage.ActualHeight}">
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage}" />
</Button>
<Button x:Name="PART_DecreaseTime"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
HorizontalContentAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Margin="0"
Padding="0"
Height="{Binding ElementName=PART_IncreaseTime, Path=ActualHeight}"
Width="{Binding ElementName=PART_IncreaseTime, Path=ActualWidth}">
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DecreaseImage}" />
</Button>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
WPF uses "lookless controls," which basically means that you can change the entire visual part (at design- or run-time) of a control without changing its code or the behavior of that code. You're already making use of this concept to create a default Style for your TimePicker control. If you were to remove the ControlTemplate from that Style, you would see nothing at runtime because the control itself is just the behavior defined in the C# or VB code.
Since it sounds like you want to keep the behavior of your buttons, but completely change the look, this is an ideal scenario for re-templating. Here's a very simple example that will show only the Content (in the ContentPresenter):
<Button Content="Hello Template">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Button.Template>
</Button>
You will probably want to add some more to the template, like a Transparent Border to catch mouse input and maybe some Triggers. The way you're attempting to use a Trigger on the ToggleButton in your example is incorrect (FrameworkElement Triggers collection only works with EventTriggers), but inside a ControlTemplate or Style, that pattern will work.
If you want to apply the same Style to every Button inside your TimePicker ControlTemplate you can add a default Button Style to the Resources collection of your ControlTemplate:
<ControlTemplate TargetType="{x:Type MyControl}">
<ControlTemplate.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ControlTemplate.Resources>
...
</ControlTemplate>

WPF - Why is my buttons content moving separately from the button itself?

I have created a TabControl in a WPF application I'm writing. I re-templated TabItem so that I could have a button on each tab header to close it. So far, all is well and good.
I decided that I now wanted shiny round buttons instead of the default square ugly things. Also, I wanted to use an image as my buttons content instead of simply setting the content to "X".
My XAML styles/templates:
<Style TargetType="{x:Type Button}" x:Key="EllipseButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding BorderThickness}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Button.Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ClosableTabItemTemplate">
<DockPanel MinWidth="120" Margin="0,0,0,0">
<ContentPresenter
Content="{Binding Path=DisplayName}"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
<Button
Command="{Binding Path=UnSubscribeApplicationCommand}"
CommandParameter="{Binding Path=DisplayName}"
BorderBrush="Black"
BorderThickness="2"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
Width="16" Height="16">
<Image Source="closeicon.bmp" Height="8" Width="8"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource EllipseButtonStyle}">
<Setter Property="Background"
Value="{StaticResource CloseOffButtonBrush}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DockPanel>
</DataTemplate>
With the above code in place, however, a selected tabs content (and the background as well) seems to shift upwards because of what I assume is the TabItems content moving upwards due to it being selected. Why, then, is the ellipse not shifting with the other content? Anyone have any idea what is going on here?
Sorry for the delayed response - I ended up solving the issue by modeling my TabItem template after the one posted in this blogpost. I believe the issue surfaced due to the fact that my TabItem template was being defined as a DataTemplate, not as a ControlTemplate as it should have been. Here is the new template:
<ControlTemplate x:Key="ClosableTabItemTemplate" TargetType="TabItem">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Background="{StaticResource TabItemUnselectedBrush}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
<DockPanel x:Name="ContentPanel">
<Button Command="{Binding Path=UnSubscribeApplicationCommand}" BorderBrush="Black" HorizontalAlignment="Center" Margin="3,0,3,0" VerticalAlignment="Center" Width="16" Height="16" DockPanel.Dock="Right" ToolTip="Close Tab">
<Button.Content>
<Image Source="pack://application:,,,/Resources/Close.png" Height="8" Width="8" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Button.Content>
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource EllipseButtonStyle}">
<Setter Property="Background" Value="{StaticResource CloseOffButtonBrush}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{Binding Path=DisplayName}" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
</Grid>
<!-- bunch of ControlTemplate triggers to style the TabItem background color/position -->
</ControlTemplate>
Whenever I have controls inside a DockPanel, it always seems to play up if one of the controls I've explicitly attached DockPanel.Dock to comes AFTER the element I want to take up the fill portion. While I don't know if this will answer your question, try this instead in your ClosableTabItemTemplate DataTemplate:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"/>
<Button Grid.Column="1"/>
</Grid>

How to make a TextBox with a Button inside in WPF?

I'd like to make a TextBox with a Button inside, something like a DatePicker, but not exactly. Or can it be a ComboBox inside the TextBox, so you can switch the mode of the TextBox.
Can you help me?
If you want something like a combobox or a date time picker you should create a new control, inside this new control place a text box and a button side by side inside a frame that looks like the frame of a textbox - then restyle the textbox so it doesn't have a frame.
putting a button inside a rich edit is great if you want to put a button inside a "document" but not a good substitute for a combobox.
See the ComboBox control template MSDN
I created a textbox control and added this
It seems to work, but not the ideal situation cos it recreates another textbox.
<TextBox.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
<TextBox Grid.Column="0"></TextBox>
<Button HorizontalAlignment="Right" Width="25" Grid.Column="1">
</Button>
</Grid>
</ControlTemplate>
</TextBox.Template>
Simple solution
You can fake the fact that the button is in the TextBox by putting the Button over the TextBox. Don’t forget to put padding on your TextBox to avoid text going behind the Button.
Code example with StackPanel :
<StackPanel Orientation="Horizontal">
<TextBox Width="200" Padding="0,0,30,0" Height="30" FontSize="16"/>
<Button Width="20" Height="20" Margin="-30,0,0,0"/>
</StackPanel>
Code example with Grid :
<Grid>
<TextBox Width="200" Padding="0,0,30,0" Height="30" FontSize="16"/>
<Button Width="20" Height="20" HorizontalAlignment="Right" Margin="0,0,5,0"/>
</Grid>
Result :
You may find this link helps: http://msdn.microsoft.com/en-us/library/ms752068(VS.85).aspx.
"The ControlTemplate for a TextBox must contain exactly one element that is tagged as the content host element; this element will be used to render the contents of the TextBox. To tag an element as the content host, assign it the special name PART_ContentHost. The content host element must be either a ScrollViewer or an AdornerDecorator. The content host element may not host any child elements."
You can use RichTextBox instead of textbox and it support flowdocument in which you can place the button in it.
You can also use a Label and change its template to include a Button in it. To have a good overview of differences between Label and TextBlock see this post.
The correct method of doing this is to use a control template on the textbox. Something like below. I used this inside a class that inherits from textbox and called it ButtonBox. I then inherit others from this such as DateBox, DateTimeBox, SqlServerConnectBox etc.
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
<TextBox.Template>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<mwt:ListBoxChrome
Background="{TemplateBinding Panel.Background}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
BorderThickness="{TemplateBinding Border.BorderThickness}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
Name="Bd"
SnapsToDevicePixels="True">
<DockPanel>
<Button DockPanel.Dock="Right" Name="myButton" Padding="3,0" Click="myButton_Click">...</Button>
<ScrollViewer Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"></ScrollViewer>
</DockPanel>
</mwt:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled">
<Setter Property="Panel.Background" TargetName="Bd">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
</Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>False</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</TextBox.Template>
Edit: I've change the method I was using so that it inherits from control and not textbox. This works well because the control just consists of a border, a textbox and a button. I was getting focus issues with the above solution. This is new template, I have called my control a ButtonBox
<Style TargetType="{x:Type local:ButtonBox}">
<Setter Property="Border.BorderThickness" Value="1"></Setter>
<Setter Property="Border.BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,20" MappingMode="Absolute">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFABADB3" Offset="0.05" />
<GradientStop Color="#FFE2E3EA" Offset="0.07" />
<GradientStop Color="#FFE3E9EF" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonBox}">
<mwt:ListBoxChrome
Background="{TemplateBinding Panel.Background}"
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
Name="Bd"
SnapsToDevicePixels="True">
<DockPanel>
<Button
DockPanel.Dock="Right"
Name="PART_Button"
Height="0"
Style="{x:Null}"
Margin="0"
Padding="3,0"
Content="{TemplateBinding local:ButtonBox.ButtonContent}"
IsTabStop="False">
</Button>
<TextBox
BorderBrush="{x:Null}"
BorderThickness="0"
Margin="0"
Name="PART_ContentHost"
IsReadOnly="{TemplateBinding TextBox.IsReadOnly}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=Text}">
</TextBox>
<!-- ScrollViewer Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Margin="1"></ScrollViewer -->
</DockPanel>
</mwt:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled">
<Setter Property="Panel.Background" TargetName="Bd">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
</Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>False</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsTabStop" Value="False"></Setter>
</Style>
Just use Grid.Column same like below code
<TextBox x:Name="txtUrl" Grid.Column="1" Margin="2,2,0,2" VerticalAlignment="Center" Padding="2" PreviewKeyDown="txtUrl_PreviewKeyDown" GotFocus="txtUrl_GotFocus" PreviewMouseDown="txtUrl_PreviewMouseDown">
</TextBox>
<eo:BareButton x:Name="btnAddFavorite" Grid.Column=" 1" HorizontalAlignment="Right" Style="{StaticResource WindowButtonStyle }" Margin="2" >
<eo:BareButton.Template>
<ControlTemplate TargetType="{x:Type eo:BareButton}">
<Border x:Name="PART_Border" Width="22" Height="22" Background="Transparent" VerticalAlignment="Center" Margin="2,0,0,0" CornerRadius="2">
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Yellow"
Data="M 2,9 L 8,8 10,2 13,8 19,9 15,13 16,19 10,15 5,19 6,13 2,9"
SnapsToDevicePixels="false"
Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type eo:BareButton}, Mode=FindAncestor}}"
StrokeThickness="1" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="PART_Border" Property="BorderBrush" Value="#666"/>
<Setter TargetName="PART_Border" Property="BorderThickness" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</eo:BareButton.Template>
</eo:BareButton>
You may use a grid to accomplish this task. The following is how I created a button which appears at the right bottom of a TextBox:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="0" />
<Button Content="Copy" Width="40" Height="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10" Grid.Row="0" />
</Grid>

Resources