I've written following xaml code to show a popup with the content in a expander control. all the things work ok up to the position where the popup opens when the button is clicked. but the popup wont close when I click away from it. plus as soon as I click away to close the popup my whole application seems to be freezed for a little amount of time. Im trying to figure out what might be the issue. could anyone assist me to find this please ?. Thanks you.
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<StackPanel>
<Button x:Name="btnTask" Content="{TemplateBinding Header}" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Label Content="{TemplateBinding Content}" Margin="2,0,2,0" />
</ControlTemplate>
</Button.Template>
<Button.ToolTip>
<Border CornerRadius="0,2,0,2" BorderBrush="White" BorderThickness="1" Background="SeaShell">
<StackPanel Width="150" Height="Auto">
<TextBlock TextWrapping="Wrap" Text="{TemplateBinding Tag}" Padding="2"/>
</StackPanel>
</Border>
</Button.ToolTip>
</Button>
<Popup x:Name="popupTask" Height="200" Width="200" StaysOpen="False">
<ContentControl Content="{TemplateBinding Content}" />
</Popup>
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger SourceName="btnTask" RoutedEvent="ButtonBase.Click">
<BeginStoryboard>
<Storyboard TargetName="popupTask">
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" BeginTime="0:0:0" Duration="0:0:3">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.2" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can use a ToggleButton instead of a Button and use a different trigger, based on the ToggleButton's property IsChecked. Here is how you can change your style:
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<StackPanel>
<ToggleButton x:Name="btnTask" Content="{TemplateBinding Header}">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Label Content="{TemplateBinding Content}" Margin="2,0,2,0" />
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.ToolTip>
<Border CornerRadius="0,2,0,2" BorderBrush="White" BorderThickness="1" Background="SeaShell">
<StackPanel Width="150" Height="Auto">
<TextBlock TextWrapping="Wrap" Text="{TemplateBinding Tag}" Padding="2"/>
</StackPanel>
</Border>
</ToggleButton.ToolTip>
</ToggleButton>
<Popup x:Name="popupTask" Height="200" Width="200" StaysOpen="False">
<ContentControl Content="{TemplateBinding Content}" />
</Popup>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger SourceName="btnTask" Property="IsChecked" Value="True">
<Setter TargetName="popupTask" Property="IsOpen" Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Related
I have found a workaround by using unicode instead of ImageAwesome but I would much rather not have to look up all of the icons' unicode of all of the font awesome icons I am using in my program.
The font awesome package I am using is: https://github.com/MartinTopfstedt/FontAwesome5
Here's a snippet of my button style:
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="1" CornerRadius="4">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource PrimClr}" />
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource SecClr}" Opacity="0.8"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource SecClr}" />
</Setter.Value>
</Setter>
<Setter Property="TextBlock.FontWeight" Value="Bold"/>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource PrimClr}" Opacity="0.8" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextBlock.FontStyle" Value="Italic"/>
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Gray" Opacity="0.3"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Here's the example of how I use a button in my program:
<Button x:Name="SubmitBtn" Grid.Column="1" Grid.Row="14" Grid.ColumnSpan="2" Width="200" Height="45" FontSize="24" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ButtonStyle}" Click="SubmitBtn_Click">
<StackPanel Orientation="Horizontal">
<fa5:ImageAwesome Icon="Solid_UserCheck" Foreground="GhostWhite" Height="24" Width="24" Margin="0,0,10,0" />
<TextBlock Text="Save Player"/>
</StackPanel>
</Button>
Please note: not putting a color for foreground results in the default black color, I at least want something to show in the mean time.
The color of the ImageAwesome does not take the styles from the button style like the textblock does... I want to be able to make it do so but I cannot find an answer anywhere! Any help would be appreciated.
Also, here's the workaround I found and I hope its not the only solution...
<Button x:Name="SubmitBtn" Grid.Column="1" Grid.Row="12" Grid.ColumnSpan="4" Width="200" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource ButtonStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="/FontAwesome.Sharp;component/fonts/#Font Awesome 5 Free Solid" Text="" FontSize="24" Margin="0,0,10,0" TextAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Submit" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</Button>
I found the solution. I should have been using FontAwesome instead of ImageAwesome.
<Button x:Name="SubmitBtn" Grid.Column="1" Grid.Row="14" Grid.ColumnSpan="2" Width="200" Height="45" FontSize="24" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ButtonStyle}" Click="SubmitBtn_Click">
<StackPanel Orientation="Horizontal">
<fa5:FontAwesome Icon="Solid_UserCheck" FontSize="24" Margin="0,0,10,0" />
<TextBlock Text="Save Player"/>
</StackPanel>
</Button>
The only problem, and its not a big deal, in the designer it shows as a square.. so I just have to make sure I'm choosing the correct icon.
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>
I have a simple style for label controls. I'd like to define a control template inside the style with a button, which could be clicked and would set the visibility property of the label to 'Hidden'. Something like this:
<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderThickness="1" Padding="4" CornerRadius="3"
BorderBrush="Gray" Background="#FFA11616">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"/>
<Button Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X">
<!-- THIS IS WRONG! HOW TO CREATE A TRIGGER FOR THIS BUTTON
HERE AND HOW TO REFER TO THE LABEL? -->
<Button.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</Trigger>
</Button.Triggers>
</Button>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is I'm not sure how to handle the click with a trigger and also how to set a property of the label that contains the button.
Thanks.
I authored this with Blend 4. Essentially you want to handle the "PreviewMouseButtonUp" event on your button with an EventTrigger. The EventTrigger will start a Storyboard which animates the UIElement.Visibility property to "Hidden" at the top of the Visual Tree for your label's style.
To get control over the content in the button, you can use the Tag Property on the label control. Otherwise, you will have to create another dependency property, and that means subclassing Label.
Inside the style, then, the <Button/> looks like this:
<Button x:Name="button" Grid.Column="1" Padding="2"
FontSize="9"
Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
...and since you can put anything into a Tag property you can do this:
<Label x:Name="label" Content="Label"
Style="{DynamicResource MessageLabel_WithCloseButton}">
<Label.Tag>
<StackPanel>
<TextBlock>WOOT</TextBlock>
<TextBlock>WOOT</TextBlock>
</StackPanel>
</Label.Tag>
</Label>
Here is a modified complete style (I also modified some things for better automatic sizing:
<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnClick1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Hidden</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="border" BorderThickness="1" Padding="4" CornerRadius="3"
BorderBrush="Gray" Background="#FFA11616">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" VerticalAlignment="Center" Margin="0,0,3,0"/>
<Button x:Name="button" Grid.Column="1" Padding="2" FontSize="9" Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="UIElement.PreviewMouseLeftButtonUp" SourceName="button">
<BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note, too, that the EventTrigger is on your ControlTemplate and not on the Button in your tree. But that might be just the way Blend generates the code.
You can use a ToggleButton instead of the normal Button and then just use the IsChecked property for the Trigger:
<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderThickness="1" Padding="4" CornerRadius="3"
BorderBrush="Gray" Background="#FFA11616">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"/>
<ToggleButton x:Name="CloseButton" Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="CloseButton" Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
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>
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>