I'm attempting to style the ListBoxItems within my listbox but the content of the ListBoxItem does not display and any change in colours are not apparent. The only thing working is the "border bottom" that I've applied to the bottom of each list item.
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" />
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use a panel/container/decorator in the ListBoxItem control template to set the background color. (It seems that the logic for setting the selection background color will interfere with attempts to control its background color.)
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
Name="PART_Border"
Focusable="true"
Background="{TemplateBinding Background}"
BorderBrush="#FF66AFDE"
BorderThickness="0 0 0 1"
>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter
Property="Background"
Value="Red"
TargetName="PART_Border"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Also note, that Border.Focusable is by default false. If setting it to true doesn't work (i admit, i haven't tested), use a different container control instead of Border.
Also, if the content you will show has any controls receiving focus (such as buttons or text fields), the trigger might not work as expected, because the Border might not have the focus when a control of the content has the focus. Also, tabbing from control to control might exhibit unexpected behaviour. If you have to deal with such a situation, try to handle the trigger in an ItemTemplate instead.
Regarding the ContentPresenter not showing anything: Depending on the type of the elements in the ItemsSource, you might need to define a ListBox.ItemTemplate (or ListBox.ItemTemplateSelector), otherwise ContentPresenter might not know what to display.
Try this
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" x:Name="border">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="border" Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I hope this will help
Related
I am trying to set inactive buttons to have semi-transparent (i.e. greyed out) images. Yet for some reason the images become white/ yellow (as if on a bright background):
As you can see it's light yellow
Possibly better annotated screenshot
Here are the XAML Styles:
<Style x:Key="ToolButton" TargetType="{x:Type Button}" BasedOn="{x:Null}">
<Setter Property="Background" Value="#888"/>
<Setter Property="Padding" Value="10,2"/>
<Setter Property="BorderThickness" Value="0"/>
<Style.Resources>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
<Style x:Key="ToolPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Background" Value="#111"/>
<Style.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ResourceKey=ToolButton}"/>
</Style.Resources>
</Style>
(StackPanel and buttons are dark for contrast, they are actually mean to be light grey)
What should I do to get the greyed out effect I want?
The problem is the default Button template: it changes its background based on the control's state, and that new background takes precedence over the one you're setting in your style.
In this case, the brush for the 'Disabled' state is something like #F4F4F4, or a very light gray.
The fix would be to declare a new Button template. For example:
<ControlTemplate TargetType="Button">
<!--Optional: Add border brush/thickness if you want a border-->
<Border x:Name="border" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentSite" Margin="{TemplateBinding Padding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<!--Optional: Remove background when disabled-->
<!--Setter TargetName="border" Property="Background" Value="Transparent" /-->
<Setter TargetName="contentSite" Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="#AAA" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Background" Value="#333" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Note that with this version, you do not need the Image style to change the Opacity; it's taken care of in the Button template.
I have a HomePage with a number of buttons on that I am trying to get to do a couple of things. Firstly, I have a Style in a ResourceDictionary that dictates the overall 'look and feel' of the buttons. It looks like this:
<Style TargetType="Button" x:Key="HomeButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#06658D"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
</Style.Triggers>
</Style>
Nothing too complicated, however I want the MouseOver effect to persist after being clicked. So now I am looking at doing something like this:
<Button Grid.Row="0" Style="{StaticResource HomeButton}" Content="Contacts">
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding ContactsClicked}" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button>
I'll bind the command element of the Button to set ContactsClicked = true and reset this when another button is pressed. However, I get the error saying that Content is set multiple times.
Is it possible to have an overall Style of the Button set, as well as a 'Clickedstyle and to have aTextBlockdisplaying text on the button all at once or am I approaching this wrong? I am trying to not have an individual overall style for every singleButton`as that's a lot of repeated code.
For clarity this is what I am aiming for:
I've managed to find a solution myself, instead of using a Button us a ToggleButton instead:
<Style TargetType="ToggleButton" x:Key="HomeButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#06658D"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
</Style.Triggers>
</Style>
I would add this as a comment but im not allowed.
If your goal is that the button will stay selected after it is clicked, why not use a RadioButton? A RadioButton has a built-in property called IsChecked but will also remain "Checked" or "Selected" even after multiple clicks.
Of course you can define the behavior and the styles in a similar manner, create a simple Trigger on the property IsChecked.
If more explanation is needed, just say so.
When i add this controltemplate my checkboxes disapear and only the checkbox text is shown. And when mouse is over the textbackground becomes red, how do i get my checkbox background red when mouse is over?
<Style TargetType="CheckBox" x:Key="Checkbox">
<Setter Property="BorderThickness" Value="2" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="20,15,0,0" />
<Setter Property="FontFamily" Value="/Resources/Fonts/Source Sans Pro/#Source Sans Pro" />
<Setter Property="FontSize" Value="14" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Foreground" Value="{DynamicResource CheckboxForegroundColor}" />
<Setter Property="Background" Value="{DynamicResource CheckboxBackgroundColor}" />
<Setter Property="BorderBrush" Value="{DynamicResource CheckboxBorderbrushColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<CheckBox Background="{TemplateBinding Background}" >
<ContentPresenter />
</CheckBox>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
This will work for some properties (try FontSize, for example), but not for others. The default template for the CheckBox has triggers of its own, and they don't bother with such things as TemplateBindings.
This post tells you how to extract the default template for a ComboBox. Here is an excerpt which shows your problem:
<ControlTemplate.Triggers>
...
<Trigger Property="IsMouseOver" Value="true">
<Setter
Property="Background"
TargetName="checkBoxBorder"
Value="{StaticResource OptionMark.MouseOver.Background}"/>
...
</Trigger>
...
</ControlTemplate.Triggers>
Your best bet is probably to override the entire template. Happily, it isn't too complex...
Remove your own template.
Follow the steps outlined in the post I linked to. That should give you a copy of the default CheckBox template.
Modify that copy. In particular, the IsMouseOver trigger that I excerpted: Change {StaticResource OptionMark.MouseOver.Background} to Red.
If this is still unclear, see this related post.
I've found this topic about setting the border of a button to transparent.
This works fine, but I want to use this for the button background and not the border.
Solution in link which I've put in <Window.Resources>...</Window.Resources>:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<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>
Source: How do you change Background for a Button MouseOver in WPF?
How can edit this code so I can use this to set the background of my button to transparent and not the border of it?
Try this snippet for a transparent button:
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0">
<-- PUT BUTTON CONTENT HERE e.g. a Image -->
</Button>
Found the solution for my issue:
Apparently you have to add the triggers within the ControlTemplate under ControlTemplate.Trigger. Andd after you've done that the thing with borders is that you have to set a TargetName in the Border tag and then set the reference (-> TargetName="XXXXX") to the properties which you've named in the border tag.
So:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="40" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Margin" Value="45,0,0,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Name="MenuBorder" SnapsToDevicePixels="True" BorderBrush="Black" Background="{TemplateBinding Background}" BorderThickness="0,0,0,2" >
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter TargetName="MenuBorder" Property="BorderBrush" Value="#FFED6A2B" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change this line
<Setter Property="Background" Value="Red"/>
to
<Setter Property="Background" Value="Transparent"/>
Use this in C# code
Button btn = new Button() {BorderBrush=System.Windows.Media.Brushes.Transparent,
BorderThickness = new Thickness(0)};
or
yourBtn.BorderBrush=System.Windows.Media.Brushes.Transparent;
yourBtn.BorderThickness =new Thickness(0);
from the following Trigger only the Foreground Setter is working. I do not understand why.
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
Thanks for any help.
The reason this doesn't work is because the default Button template uses a ButtonChrome that draws the border and background and handles states like mouseover and disabled depending on the Windows theme (e.g. Windows XP style, Windows 7 style).
In order to allow your triggers to be applied, you will need to define a custom Button template that uses standard stylable WPF elements, like Border, instead of ButtonChrome. Here's a bare-bones working example:
<Button Content="button">
<Button.Style>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Property=Background}"
BorderBrush="{TemplateBinding Property=BorderBrush}"
BorderThickness="{TemplateBinding Property=BorderThickness}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="Foreground" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Button in WPF has a default control template. The correct way to override the Button's default behavior is by overriding default control template. This can be done with something similar to below:
<Button Width="100" Height="50" Content="Click Me!">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bdr_main" CornerRadius="20" Margin="4" BorderThickness="1" BorderBrush="Black" Background="LightGray">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="8,6,8,6" ContentSource="Content" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bdr_main" Property="Background" Value="LightGreen"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="bdr_main" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
Found # http://harishasanblog.blogspot.com/2011/02/ismouseover-trigger-not-working-in-wpf.html
Hope it helps!
Try using the trigger on the controltemplate.
<ResourceDictionary>
<Style x:Key="TestButton" TargetType="Button">
<Setter Property="Height" Value="30" />
<Setter Property="Width" Value="30" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Green" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Purple" />
</Trigger>
</ControlTemplate.Triggers>
<Grid>
<Rectangle Fill="{TemplateBinding Foreground}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>