wpf tabitem with image - wpf

I need to use, with a stile of mahapps.metro, the tabitem with a text and an image..
this is my code:
<TabItem Style="{StaticResource gMetroTabItem}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Name="img" Height="auto" Width="auto" Source="/myProject;component/Resources/Black_Tools.png" />
<TextBlock Text="tabItem2" Margin="2,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
</TabItem>
and this is the code of the style:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type TabControl}" x:Key="gMetroTabControl">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Style>
<Style TargetType="TabItem" x:Key="gMetroTabItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="6,2,6,2" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="MinWidth" Value="5" />
<Setter Property="MinHeight" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Label x:Name="root" FontSize="46.67">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" />
</Label>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="root" Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource AccentColor}" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter TargetName="root" Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource GrayNormal}" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger SourceName="root" Property="IsMouseOver" Value="True">
<Setter TargetName="root" Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="Lime" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<!--<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<AdornerDecorator>
<ContentPresenter Content="{Binding}"/>
</AdornerDecorator>
</DataTemplate>
</Setter.Value>
</Setter>-->
</Style>
</ResourceDictionary>
but doesn't work, 'cause the style go to change a text property, and the image isn't displayed..
any ideas?

From the screencast images you posted:
designtime: http://www.screencast.com/t/TV20zfCi
runtime: http://www.screencast.com/t/7w9rBBEkhMnH
This is indicative of the Black_Tools.png having incorrect properties. Make sure the image is set to be a resource and copied to the output directory:
Right Click Black_Tools.png in the solution explorer > Properties
Build Action: Resource
Copy to Output Directory: Copy always (or Copy if newer)
If the image isn't set as a resource and copied to the output directory, then you'll see the image at design time since the image can be resolved in the solution. However, at runtime, the image path is different since the files will be in the project's output directory.

Scratch what I said before. This is much easier.
You only need the TabControl.ItemTemplate. This is what determines the layout of the header. With some tricky binding to ancestor, you can bind to the TabItem's properties for your DataTriggers.
In this example I show how to bind to the IsSelectedProperty. I'll leave the IsMouseOver as an exercise for you. Hint: Bind to the IsMouseOver using ElementName "root", and then in the setter use TargetName="root".
<Style TargetType="{x:Type TabControl}" x:Key="gMetroTabControl">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type local:TabItemHeaderData}">
<StackPanel>
<TextBlock Name="root" Text="{Binding LabelText}"/>
<Rectangle Fill="{Binding RectFill}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,AncestorType={x:Type TabItem}},Path=IsSelected}" Value="true">
<Setter TargetName="root" Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="Blue" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,AncestorType={x:Type TabItem}},Path=IsSelected}" Value="false">
<Setter TargetName="root" Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type local:TabItemHeaderData}">
<ContentControl Content="{Binding Content}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Then you'll need to create a dataobject.
public class TabItemHeaderData
{
public Brush RectColor { get; set; }
public String LabelText { get; set; }
public object Content { get; set; }
}
Then you just set the values in the dataobject like so.
<TabControl Style="{StaticResource gMetroTabControl}">
<local:TabItemHeaderData RectColor="Black" LabelText="John">
<local:TabItemHeaderData.Content>
<Button>George</Button>
</local:TabItemHeaderData.Content>
</local:TabItemHeaderData>
<local:TabItemHeaderData RectColor="Black" LabelText="John">
</local:TabItemHeaderData>
</TabControl>

Related

How to style tabitem same same height level top?

I custom to stlye tab item. but the first child dont same level with content area. picture. How to fix this. default tabcontrol thers border around border around tabitem.
<Application.Resources>
<Style x:Key="BlueOcean" TargetType="{x:Type TabControl}">
<Style.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Height" Value="50" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<StackPanel Name="Panel">
<ContentPresenter
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="LightSkyBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
</Application.Resources>
TabControl View
<TabControl Style="{DynamicResource BlueOcean}" TabStripPlacement="Left">
<TabItem Header="Home" Content="Home Page" />
<TabItem Header="Settings" Content="Settings Page" />
</TabControl>

WPF- How to refactor multiple ListViewItem Style Template with few changes?

I'm using custom style selector on list view to change CornerRadius / BorderThickness for first and last item.
I need to have this presentaion with Enum binding on listview
Code of the list view with ItemContainerStyleSelector
<ListView ItemsSource="{Binding ItemsSource, ElementName=Self, Mode=TwoWay}"
FocusVisualStyle="{x:Null}"
BorderThickness="0"
SelectedValue="{Binding SelectedValue, ElementName=Self, Mode=TwoWay}"
HorizontalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Background="Transparent">
<ListView.ItemContainerStyleSelector>
<enumToggleButtonList:FirstLastItemStyleSelector
DefaultStyle="{StaticResource AllItemStyle}"
StyleFirst="{StaticResource FirstItemStyle}"
StyleLast="{StaticResource LastItemStyle}"/>
</ListView.ItemContainerStyleSelector>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid FlowDirection="LeftToRight" Rows="1"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
I have 3 styles : default / first / last like this
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="0"
BorderThickness="1,1,0,1">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="0,5,5,0">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
.... same
</Style>
<Style x:Key="FirstItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="5,0,0,5"
BorderThickness="1,1,0,1">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
.... same
</Style>
And globally changes are for the border :
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="5,0,0,5"
BorderThickness="1,1,0,1">
There are any methods to refactor this without using code behind plz ? Or another way to do that ?
You can simplify your styles by utilizing attached properties. But that does require you creating a simple attached properties class.
using System.Windows;
namespace SO
{
public static class ListViewItemProperties
{
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.RegisterAttached(
"CornerRadius",
typeof(Thickness),
typeof(ListViewItemProperties),
new PropertyMetadata(new Thickness(0d)));
public static Thickness GetCornerRadius(DependencyObject obj)
{
return (Thickness)obj.GetValue(CornerRadiusProperty);
}
public static void SetCornerRadius(DependencyObject obj, Thickness value)
{
obj.SetValue(CornerRadiusProperty, value);
}
}
}
And there are the updated (and simplified) styles that use the attached property:
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
BorderThickness="1,1,0,1"
CornerRadius="{TemplateBinding local:ListViewItemProperties.CornerRadius}"
Style="{StaticResource BorderListViewItemStyle}">
<TextBlock x:Name="TemplateTextBlock"
Style="{StaticResource TextblockListViewItemStyle}"
Text="{Binding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}" />
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}" />
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter
Event="PreviewMouseLeftButtonDown"
Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" BasedOn="{StaticResource AllItemStyle}" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="0,5,5,0" />
</Style>
<Style x:Key="FirstItemStyle" BasedOn="{StaticResource AllItemStyle}" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="5,0,0,5" />
</Style>
The most simplest /sexy solution to do that is for the moment TemplateBinding ... I just discovered how it work ... learning is hard .. but the way after is easier x)
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="Border.CornerRadius" Value="0"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="{TemplateBinding Border.CornerRadius}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" TargetType="ListViewItem" BasedOn="{StaticResource AllItemStyle}">
<Setter Property="Border.CornerRadius" Value="0,10,10,0"/>
</Style>
<Style x:Key="FirstItemStyle" TargetType="ListViewItem" BasedOn="{StaticResource AllItemStyle}">
<Setter Property="Border.CornerRadius" Value="10,0,0,10"/>
<Setter Property="BorderThickness" Value="1,1,0,1"/>

ComboxBox Item mouse over color not working

I have a ComboBox with following xaml. Problem is I want the ComboxItem's background to be green when mouse over occurs but it dosen't work. I tried solution posted here ComboBox item color but it dosen't help.
I also tried editing the ComBoxItem's template like in the commented code. But none of the solutions work. Please help.
In the window resources I have the following items defined
<lib:MetroWindow.Resources>
<converter:EnumToVisibilityConverter
x:Key="EnumToVisibility"></converter:EnumToVisibilityConverter>
<x:Array
Type="{x:Type sys:String}"
x:Key="ImageFormatsArray">
<sys:String>Bmp</sys:String>
<sys:String>Png</sys:String>
<sys:String>Jpg</sys:String>
<sys:String>Tif</sys:String>
<sys:String>Gif</sys:String>
</x:Array>
</lib:MetroWindow.Resources>
<ComboBox
x:Name="CmbItems"
HorizontalAlignment="Left"
SelectedIndex="0"
ItemsSource="{StaticResource ImageFormatsArray}"
SelectedValue="{Binding SelectedImageFormat}">
<ComboBox.Resources>
<SolidColorBrush
x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Green" />
</ComboBox.Resources>
<!--<ComboBox.ItemContainerStyle>
<Style
TargetType="{x:Type ComboBoxItem}">
<Setter
Property="Background"
Value="{StaticResource ControlsDarkBackgroundBrush}"></Setter>
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ComboBoxItem}">
<ControlTemplate.Triggers>
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
Property="Background"
Value="{StaticResource ControlsDarkBackgroundBrush}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>-->
<!--<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding}">
<TextBlock.Style>
<Style
TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
Property="Background"
Value="Black"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>-->
</ComboBox>
</StackPanel>
here is a working example, take what you need
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
<StackPanel Background="{TemplateBinding Background}" >
<ContentPresenter></ContentPresenter>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>

XAML Trigger WPF Tab selection changes more than the tab header

I have a trigger that when a tab is selected I color the tab blue and the text white, but the problem is that this trigger, for some reason, also changes the text color in the tabheader body to white as well in the group boxes. It seems that anything that has a header turns to white.
How do I make it so only the header in the tab itself
<TabItem Header="Query Editor" <-- This text only
will change to white when selected and no other text on the form?
Below is the code I am using.
Thanks.
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border"
Background="WhiteSmoke"
BorderBrush="Black"
BorderThickness="1,1,1,1"
CornerRadius="6,6,0,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="#00396a" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="WhiteSmoke" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
may be TabItem.HeaderTemplate will work for you.
<TabControl>
<TabControl.Resources>
<DataTemplate x:Key="headerText">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock x:Name="content" Text="{Binding}" Grid.Column="1"/>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter TargetName="content" Property="Foreground" Value="white" />
</Trigger.Setters>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="TabItem">
<Style.Setters>
<Setter Property="HeaderTemplate" Value="{StaticResource headerText}" />
</Style.Setters>
</Style>
</TabControl.Resources>
<TabItem Header="fsdf" >
<TextBlock Text="lkajsldkjaskl" />
</TabItem>
<TabItem Header="ghj">
<TextBlock Text="ghj" />
</TabItem>
<TabItem Header="fs556df">
<TextBlock Text="jjj" />
</TabItem>
</TabControl>
</TabItem>
</TabControl>
you could have 2headerstyle, one normal one selected. in your tabitem style triggers you can set the headertemplate to the right "IsSelected" one.
The solution!
Thank you all for your help.
What I changed was I removed the ContentPresenter and replaced it with the textblock that only affected the tab header itself.
<TabControl.Resources>
<Style TargetType="{x:Type TabControl}">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0" Color="WhiteSmoke"/>
<GradientStop Offset="4" Color="GhostWhite"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Black" />
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border"
Background="WhiteSmoke"
BorderBrush="Black"
BorderThickness="1,1,1,1"
CornerRadius="6,6,0,0">
<TextBlock
x:Name="TabItemContent"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{TemplateBinding Header}"
Margin="12,2,12,2" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="#00396a" />
<Setter Property="Foreground" TargetName="TabItemContent" Value="White"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="WhiteSmoke" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>

Link button in wpf

How can I make Button to look like LinkButton, and I don't want to use
Hyperlink...!!
Any suggestions
If you don't want any of the normal Button style and just want something that looks like a hyperlink you could start with this
<Button Margin="5" Content="Test" Cursor="Hand">
<Button.Template>
<ControlTemplate TargetType="Button">
<TextBlock TextDecorations="Underline">
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Button.Template>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Here's the same as a style:
<Style
x:Key="LinkButton"
TargetType="Button">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="Button">
<TextBlock
TextDecorations="Underline">
<ContentPresenter /></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter
Property="Foreground"
Value="Blue" />
<Style.Triggers>
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
Property="Foreground"
Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
and you can use it like this:
<Button Style="{StaticResource LinkButton}" Content="Clicky" />
<Style x:Key="LinkButton"
TargetType="Button"
BasedOn="{StaticResource ResourceKey={x:Type Button}}"
>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="Center"
>
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations" Value="Underline" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Blue" />
<Setter Property="Cursor" Value="Hand" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
MichaC's and Anderson's version placed the underline slightly wrong, here is an updated version that will just add an underline to any TextBlock that are inside the ContentPresenter.
Here's MichaC's suggestion implemented as a Style that you can reuse on any button:
<Style x:Key="LinkButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock TextDecorations="Underline">
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Blue" />
<Setter Property="Cursor" Value="Hand" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
The easiest way (I do this in my application):
<TextBlock Name="..."
Text="..."
Cursor="Hand"
Foreground="Blue"
TextDecorations="Underline"
MouseLeftButtonUp=..."
/>
you have full control on TextDecoration, e.g. change pen style or offset.
take a look at this link to find out more: http://msdn.microsoft.com/en-us/library/system.windows.textdecorations.underline.aspx
Another solution using Hyperlink is to put in inside TextBlock.
<TextBlock>
<Hyperlink Click="...">
<TextBlock Text="Link text" />
</Hyperlink>
</TextBlock>
Why do you not want to use Hyperlink?
<Button>
<Hyperlink>
</Button>
Combination of all proposed solutions:
Completed style, as in the accepted version, but without hardcoded values.
<Style
x:Key="HyperlinkButton"
TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Type Button}}"
>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock>
<Hyperlink
Command="{TemplateBinding Command}"
CommandTarget="{TemplateBinding CommandTarget}"
CommandParameter="{TemplateBinding CommandParameter}"
>
<ContentPresenter />
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources