I'm trying to create a ListBoxItem template, that will be with rounded border at selection.
I got this xaml, which doesn't work on selection:
<ListBox x:Name="filtersListBox" Grid.Row="1"
Background="Transparent" BorderThickness="0"
ItemsSource="{Binding FilterItems}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
</Style.Resources>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center">
<Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange"
Margin="2" Background="Transparent" Name="itemBorder"
Width="275" VerticalAlignment="Center"
FocusManager.IsFocusScope="True" Focusable="True">
<Border.Effect>
<DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
</Border.Effect>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="UIElement.IsFocused" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
<EventTrigger RoutedEvent="Border.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.25"
To="2"
Storyboard.TargetProperty="BorderThickness"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Border.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.25"
To="0"
Storyboard.TargetProperty="BorderThickness"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding Text}" Margin="10, 2"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So this is the ListBox that I'm working on.
The MouseEnter and MouseLeave events, work great!
However, the trigger of UIElement.IsFocused is not working.
Any advice would be very appreciated! :)
Thanks, Alex.
This is so easy to do, I'm quite surprised that nobody suggested this yet. Either define two DataTemplates or two ControlTemplates, one for the default look and one for the selected look. Then just add this Style (this first example uses DataTemplates):
<Style x:Key="SelectionStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource DefaultTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
You would use it like this:
<ListBox ItemContainerStyle="{StaticResource SelectionStyle}" ... />
Here is the other example using two ControlTemplates (used in the same way):
<Style x:Key="SelectionStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template" value="{StaticResource DefaultTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Template" value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
I'll leave you to define what you want the items to look like as you know that best. One last note... if you use this method (using ControlTemplates), make sure that you add a ContentPresenter so that the content of the items will still be shown. See the Control.Template Property page on MSDN for an example.
Have you tried setting Focusable property to true. By default the propery is false.
Take a look at this link:
http://msdn.microsoft.com/en-us/library/system.windows.uielement.focusable%28v=vs.110%29.aspx
If that doesnt help then maybe this approach will fit you more.
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="GotFocus" Handler="ListBoxItem_GotFocus"/>
<EventSetter Event="LostFocus" Handler="ListBoxItem_LostFocus"/>
</Style>
</ListBox.Resources>
Why dont you set the Template for ItemContainerStyle, then you can use the Trigger with property IsSelected = true. See code below:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<collections:ArrayList x:Key="StringArray">
<system:String>Hei</system:String>
<system:String>Hei</system:String>
<system:String>Hei</system:String>
<system:String>Hei</system:String>
</collections:ArrayList>
</Window.Resources>
<Grid>
<ListBox x:Name="filtersListBox" Grid.Row="1"
Background="Transparent" BorderThickness="0"
ItemsSource="{StaticResource StringArray}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange"
Margin="2" Background="Transparent" Name="itemBorder"
Width="275" VerticalAlignment="Center"
FocusManager.IsFocusScope="True" Focusable="True">
<Border.Effect>
<DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
</Border.Effect>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="itemBorder" Property="Background" Value="Blue"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
</Style.Resources>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center">
<Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange"
Margin="2" Background="Transparent" Name="itemBorder"
Width="275" VerticalAlignment="Center"
FocusManager.IsFocusScope="True" Focusable="True">
<Border.Effect>
<DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
</Border.Effect>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="UIElement.IsFocused" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
<EventTrigger RoutedEvent="Border.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.25"
To="2"
Storyboard.TargetProperty="BorderThickness"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Border.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.25"
To="0"
Storyboard.TargetProperty="BorderThickness"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding }" Margin="10, 2"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Related
I have a button on my page with this XAML:
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom"
Width="50" Height="50" HorizontalContentAlignment="Left"
BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But when I put mouse over my button, button's background changes to default windows gray background.What's The Problem?
This is the button picture before and after mouseover:
Before:
After:
To remove the default MouseOver behaviour on the Button you will need to modify the ControlTemplate. Changing your Style definition to the following should do the trick:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
EDIT: It's a few years late, but you are actually able to set the border brush inside of the border that is in there. Idk if that was pointed out but it doesn't seem like it was...
All of the answers so far involve completely replacing the default button behavior with something else. However, IMHO it is useful and important to understand that it's possible to change just the part you care about, by editing the existing, default template for a XAML element.
In the case of dealing with the hover effect on a WPF button, the change in appearance in a WPF Button element is caused by a Trigger in the default style for the Button, which is based on the IsMouseOver property and sets the Background and BorderBrush properties of the top-level Border element in the control template. The Button element's background is underneath the Border element's background, so changing the Button.Background property doesn't prevent the hover effect from being seen.
With some effort, you could override this behavior with your own setter, but because the element you need to affect is in the template and not directly accessible in your own XAML, that approach would be difficult and IMHO overly complex.
Another option would be to make use the graphic as the Content for the Button rather than the Background. If you need additional content over the graphic, you can combine them with a Grid as the top-level object in the content.
However, if you literally just want to disable the hover effect entirely (rather than just hiding it), you can use the Visual Studio XAML Designer:
While editing your XAML, select the "Design" tab.
In the "Design" tab, find the button for which you want to disable the effect.
Right-click that button, and choose "Edit Template/Edit a Copy...". Select in the prompt you get where you want the new template resource to be placed. This will appear to do nothing, but in fact the Designer will have added new resources where you told it, and changed your button element to reference the style that uses those resources as the button template.
Now, you can go edit that style. The easiest thing is to delete or comment-out (e.g. Ctrl+E, C) the <Trigger Property="IsMouseOver" Value="true">...</Trigger> element. Of course, you can make any change to the template you want at that point.
When you're done, the button style will look something like this:
<p:Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</p:Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<!--<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>-->
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</p:Style>
(Note: you can omit the p: XML namespace qualifications in the actual code…I provide them here only because the Stack Overflow XML code formatter gets confused by <Style/> elements that don't have a fully-qualified name with XML namespace.)
If you want to apply the same style to other buttons, you can just right-click them and choose "Edit Template/Apply Resource" and select the style you just added for the first button. You can even make that style the default style for all buttons, using the normal techniques for applying a default style to elements in XAML.
This worked well for me.
Button Style
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="Transparent">
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Button
<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
Command="{Binding CloseWindow}">
<Button.Content >
<Grid Margin="0 0 0 0">
<Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
</Grid>
</Button.Content>
</Button>
Notes
The button displays a little blue cross, much like the one used to close a window.
By setting the background of the grid to "Transparent", it adds a hittest, which means that if the mouse is anywhere over the button, then it will work. Omit this tag, and the button will only light up if the mouse is over one of the vector lines in the icon (this is not very usable).
Just want to share my button style from my ResourceDictionary that i've been using.
You can freely change the onHover background at the style triggers.
"ColorAnimation To = *your desired BG(i.e #FFCEF7A0)". The button BG will also automatically revert to its original BG after the mouseOver state.You can even set how fast the transition.
Resource Dictionary
<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Arial Narrow"/>
<Setter Property="FontSize" Value="12px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="1" Color="White"/>
</Setter.Value>
</Setter>
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Opacity="1" Color="#28C2FF" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="4,2"
BorderBrush="Gray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#D2F898"
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
all you have to do is call the style.
Example Implementation
<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">
<StackPanel>
<TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
</StackPanel>
</Button>
A slight more difficult answer that uses ControlTemplate and has an animation effect
(adapted from https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control)
In your resource dictionary define a control template for your button like this one:
<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
<Border Name="RootElement">
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Black"/>
</Border.Background>
<Grid Margin="4" >
<Grid.Background>
<SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
</Grid.Background>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
in your XAML you can use the template above for your button as below:
Define your button
<Button Template="{StaticResource testButtonTemplate2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White">My button</Button>
Hope it helps
For change button style
1st: define resource styles
<Window.Resources>
<Style x:Key="OvergroundIn" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF16832F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF06731F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="OvergroundOut" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFF35E5E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFE34E4E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
2nd define button code
<Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2" >
<Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
<Button.Content>
<Grid>
<TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock>
</Grid>
</Button.Content>
</Button>
</Border>
3th code behind
public void ShowStatus()
{
switch (((MainDto)this.DataContext).State)
{
case State.IN:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
this.btnFichar.Style = Resources["OvergroundIn"] as Style;
this.btnFichar.Content = "Fichar Salida";
break;
case State.OUT:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
this.btnFichar.Style = Resources["OvergroundOut"] as Style;
this.btnFichar.Content = "Fichar Entrada";
break;
}
}
I want to ad button group instead radio button.. there is three buttons. all three buttons are same color(blue). when user click on 1st button it will change that button color as red. But when user click on second button, first button must turn into blue color and clicked button(2nd button) must turn in to red. In my code that's not change. Help me
<Button Background="#0D47A1" Command="{Binding LanguageChangeCommand}" CommandParameter="Sinhala" Content="සිංහල" Grid.Column="3" HorizontalAlignment="Left" Margin="0,10,0,0" Grid.Row="3" FontSize="20" VerticalAlignment="Top" Foreground="White" Height="37" Width="81">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="#2E8B57"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="10"/>
</Style>
</Button.Resources>
</Button>
<Button Command="{Binding LanguageChangeCommand}" Background="#0D47A1" CommandParameter="English" Content="English" Grid.Column="3" HorizontalAlignment="Left" Margin="110,15,0,0" Grid.Row="3" FontSize="20" VerticalAlignment="Top">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="#2E8B57"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="10"/>
</Style>
</Button.Resources>
</Button>
<Button Command="{Binding LanguageChangeCommand}" Background="#0D47A1" CommandParameter="Tamil" Content="தமிழ்" Grid.Column="3" HorizontalAlignment="Left" Margin="215,15,0,0" Grid.Row="3" FontSize="20" VerticalAlignment="Top" Foreground="#DDFDF9F9">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="#2E8B57"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="10"/>
</Style>
</Button.Resources>
</Button>
Button Group? Another idea is ListBox with styled ListBoxItem.
<ListBox VerticalAlignment="Top">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="border"
Padding="3" Background="SkyBlue"
BorderBrush="DeepSkyBlue" BorderThickness="1">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="OrangeRed" />
<Setter TargetName="border" Property="Background" Value="HotPink" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="1" />
<ListBoxItem Content="2" IsSelected="True" />
<ListBoxItem Content="3" />
<ListBoxItem Content="4" />
</ListBox>
The benefit of ListBox is that you can use binding and easily to get the value of selected "button" by the user.
I have a button on my page with this XAML:
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom"
Width="50" Height="50" HorizontalContentAlignment="Left"
BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But when I put mouse over my button, button's background changes to default windows gray background.What's The Problem?
This is the button picture before and after mouseover:
Before:
After:
To remove the default MouseOver behaviour on the Button you will need to modify the ControlTemplate. Changing your Style definition to the following should do the trick:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
EDIT: It's a few years late, but you are actually able to set the border brush inside of the border that is in there. Idk if that was pointed out but it doesn't seem like it was...
All of the answers so far involve completely replacing the default button behavior with something else. However, IMHO it is useful and important to understand that it's possible to change just the part you care about, by editing the existing, default template for a XAML element.
In the case of dealing with the hover effect on a WPF button, the change in appearance in a WPF Button element is caused by a Trigger in the default style for the Button, which is based on the IsMouseOver property and sets the Background and BorderBrush properties of the top-level Border element in the control template. The Button element's background is underneath the Border element's background, so changing the Button.Background property doesn't prevent the hover effect from being seen.
With some effort, you could override this behavior with your own setter, but because the element you need to affect is in the template and not directly accessible in your own XAML, that approach would be difficult and IMHO overly complex.
Another option would be to make use the graphic as the Content for the Button rather than the Background. If you need additional content over the graphic, you can combine them with a Grid as the top-level object in the content.
However, if you literally just want to disable the hover effect entirely (rather than just hiding it), you can use the Visual Studio XAML Designer:
While editing your XAML, select the "Design" tab.
In the "Design" tab, find the button for which you want to disable the effect.
Right-click that button, and choose "Edit Template/Edit a Copy...". Select in the prompt you get where you want the new template resource to be placed. This will appear to do nothing, but in fact the Designer will have added new resources where you told it, and changed your button element to reference the style that uses those resources as the button template.
Now, you can go edit that style. The easiest thing is to delete or comment-out (e.g. Ctrl+E, C) the <Trigger Property="IsMouseOver" Value="true">...</Trigger> element. Of course, you can make any change to the template you want at that point.
When you're done, the button style will look something like this:
<p:Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</p:Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<!--<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>-->
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</p:Style>
(Note: you can omit the p: XML namespace qualifications in the actual code…I provide them here only because the Stack Overflow XML code formatter gets confused by <Style/> elements that don't have a fully-qualified name with XML namespace.)
If you want to apply the same style to other buttons, you can just right-click them and choose "Edit Template/Apply Resource" and select the style you just added for the first button. You can even make that style the default style for all buttons, using the normal techniques for applying a default style to elements in XAML.
This worked well for me.
Button Style
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="Transparent">
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Button
<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
Command="{Binding CloseWindow}">
<Button.Content >
<Grid Margin="0 0 0 0">
<Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
</Grid>
</Button.Content>
</Button>
Notes
The button displays a little blue cross, much like the one used to close a window.
By setting the background of the grid to "Transparent", it adds a hittest, which means that if the mouse is anywhere over the button, then it will work. Omit this tag, and the button will only light up if the mouse is over one of the vector lines in the icon (this is not very usable).
Just want to share my button style from my ResourceDictionary that i've been using.
You can freely change the onHover background at the style triggers.
"ColorAnimation To = *your desired BG(i.e #FFCEF7A0)". The button BG will also automatically revert to its original BG after the mouseOver state.You can even set how fast the transition.
Resource Dictionary
<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Arial Narrow"/>
<Setter Property="FontSize" Value="12px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="1" Color="White"/>
</Setter.Value>
</Setter>
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Opacity="1" Color="#28C2FF" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="4,2"
BorderBrush="Gray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#D2F898"
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
all you have to do is call the style.
Example Implementation
<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">
<StackPanel>
<TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
</StackPanel>
</Button>
A slight more difficult answer that uses ControlTemplate and has an animation effect
(adapted from https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control)
In your resource dictionary define a control template for your button like this one:
<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
<Border Name="RootElement">
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Black"/>
</Border.Background>
<Grid Margin="4" >
<Grid.Background>
<SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
</Grid.Background>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
in your XAML you can use the template above for your button as below:
Define your button
<Button Template="{StaticResource testButtonTemplate2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White">My button</Button>
Hope it helps
For change button style
1st: define resource styles
<Window.Resources>
<Style x:Key="OvergroundIn" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF16832F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF06731F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="OvergroundOut" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFF35E5E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFE34E4E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
2nd define button code
<Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2" >
<Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
<Button.Content>
<Grid>
<TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock>
</Grid>
</Button.Content>
</Button>
</Border>
3th code behind
public void ShowStatus()
{
switch (((MainDto)this.DataContext).State)
{
case State.IN:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
this.btnFichar.Style = Resources["OvergroundIn"] as Style;
this.btnFichar.Content = "Fichar Salida";
break;
case State.OUT:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
this.btnFichar.Style = Resources["OvergroundOut"] as Style;
this.btnFichar.Content = "Fichar Entrada";
break;
}
}
I am making a card game and I want to display cards in player's hand half-covered be each other. How can I do that using ListView or StackPanel? Here is an example how I would like to display player hand.
<Grid Background="Green" >
<Image x:Name="One" Width="100" Height="100" Margin="10,10,250,210"/>
<Image x:Name="Two" Width="100" Height="100" Margin="10,10,210,210"/>
</Grid>
UPDATE
I set margins for ListView's ItemContainerStyle and it worked, but I have another problem. Width of ListView items doesn't fit the image and there is some spacing. How do I remove that. See image below the XAML code.
<ListView Grid.Row="0" Grid.Column="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0, 0, -80, 0"></Setter>
<Setter Property="Height" Value="100"></Setter>
<Setter Property="Width" Value="100"></Setter>
</Style>
</ListView.ItemContainerStyle>
<Image x:Name="One" MaxWidth="100" Height="100" />
<Image x:Name="Two" MaxWidth="100" Height="100" />
</ListView>
I would use Canvas in the list, and draw your card to the canvas, because things drawn in a canvas are not clipped, and instead managed through the canvas ZIndex etc.
Size the canvas based on your desired spacing, and oversize the contents. I'd also recommend binding to Items-source when using listboxes and using templates.
BTW I'm defining my cards using solidColorBrushes so I can just draw rectangles, replace this with your image source. I've defined my source in the resources, but in reality it would be bound to an ObservableCollection (Say, PlayersCurrentHand or something):
<UserControl.Resources>
<x:Array Type="{x:Type SolidColorBrush}" x:Key="Cards">
<SolidColorBrush Color="Blue"/>
<SolidColorBrush Color="Red"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
</x:Array>
</UserControl.Resources>
Now, I presume you are using ListBox because you want to support selection? If so, the way WPF highlights list box items will mess up with this overlap, so we will need to replace it. If you don't want selection, just use an itemsControl and you can skip all the selection stuff.
Here's our basic listbox:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="112,98,-325,-25" Width="513" Height="227">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<Rectangle Fill="{Binding}" Width="60" Height="100"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Which gives us this:
Now, we want to have all the list items to be drawn in a canvas, so let's define our ItemContainerStyle:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<ContentPresenter />
</Canvas>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
See how we've set the canvas Width to 15? That defines the spacing of our cards. All the canvases are stacked at intervals of 15. However, the Rectangles we are drawing in our DateTemplate is Width 60, so these spill off to the right.
We've overridden the messy standard selection and highlighting styles. But no we don't know what's highlighted and selected, so let's add some functionality back in. We can also add things like shadows etc:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<Rectangle Fill="#50000000" Width="60" Height="100" Margin="5,0,-5,0"/>
<ContentPresenter />
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
So now we have this:
Note, the gif didn't render the selection exactly right. The width issue is going to be tricky to fix without some code behind I think. One option is to make an IValueConverter that calculates width given the List of cards, and binding it to the Listview's Width property.
Edit
Found a way to get around the size issue! Padding! Of course. However, I found the scroll viewer clips even the canvas it contains (which makes sense if you think about it) but leaves all our effort hidden:
So you have to overwrite the scroll viewer functionality by setting the ControlTemplate manually:
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
So now the padding accounts for the last card sticking out an extra 50.
Total code, with some more visual tweaks:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20" BorderBrush="Black">
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" ClipToBounds="False" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter"/>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-5"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="#60000000" BorderThickness="0" CornerRadius="5" Height="100" Margin="5,0,-5,0"/>
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="{Binding}" Width="60" Height="100"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It's pretty flexible, it was easy to add the "sticking out" functionality. Animations would be the next big step.
Edit 2
I'm just playing now. I'm not sure I like the "jump to the front" functionality, would be better if they just peeked out. Also, fanning them out (using a multi-binding):
Using the following template:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter">
<ContentPresenter.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="TranslateTransformHighlight"/>
<RotateTransform x:Name="RotateTransformHighlight" CenterY="100"/>
<TranslateTransform x:Name="TranslateTransformSelect"/>
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="-15" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
I'm setting extra ToolTip for a field with errors in ResourceDictionary
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
I also defined special style for this tooltip, which simulate the one on red triangle in right upper corner
<Style TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Placement" Value="Right"/>
<Setter Property="HorizontalOffset" Value="5"/>
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Name="Border"
Background="Red"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<ContentPresenter Margin="5 2 5 3"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Opened">
<BeginStoryboard>
<Storyboard TargetProperty="HorizontalOffset">
<DoubleAnimation From="0" To="5" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Everything works, but now ALL ToolTips have this style.
Is it possible to achieve that ToolTip style take his part only if Validation.HasError occurs? I can as x:Key, but how to apply that to Style.Triggers part?
Because I have this ToolTip defined also on other controls I wouldn't like to copy all this code multiple times, but if only that is a solution I will do so :(
After another couple of hours of Googling I try the solution provided here
https://social.msdn.microsoft.com/Forums/vstudio/en-US/10d2ecbf-9e6e-4414-b57e-79dd02e0944e/changing-style-of-tooltip-in-textbox
and it works!
A created ToolTip style
<ToolTip x:Key="ErrorToolTip"
Placement="Right"
Background="Red"
Foreground="White"
BorderThickness="0"
DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<ToolTip.Content>
<Binding Path="(Validation.Errors)[0].ErrorContent"/>
</ToolTip.Content>
<ToolTip.Triggers>
<EventTrigger RoutedEvent="ToolTip.Opened">
<BeginStoryboard>
<Storyboard TargetProperty="HorizontalOffset">
<DoubleAnimation From="0" To="5" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToolTip.Triggers>
</ToolTip>
and changed Style.Triggers to
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{StaticResource ErrorToolTip}" />
</Trigger>
</Style.Triggers>
Need to do some more styling, but it's OK for now.
You can set the property Validation.ErrorTemplate on the TextBox style:
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate"
Value="{StaticResource ValidationTemplate}" />
<Style.Triggers>
<Trigger Property="Validation.HasError"
Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
However, this way you can't work with a ToolTip style, but you have to work with a template and a x:Key.
<ControlTemplate x:Key="ValidationTemplate">
<Border Name="Border"
Background="Red"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<ContentPresenter Margin="5 2 5 3"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Opened">
<BeginStoryboard>
<Storyboard TargetProperty="HorizontalOffset">
<DoubleAnimation From="0" To="5" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>