RadioButton change background color when checked - wpf

I want to override a RadioButton style to look like ToggleButton one
<RadioButton Content="Point">
<RadioButton.Template>
<ControlTemplate>
<ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
I need to change the background color of the button when it's checked. I tried with the trigger but it's not working.

The solution is not a simple one. The issue is related to the fact that the togglebutton has a default background when it is checked, and that one has to be removed, before changing it to a different one.
Take a look at this topic: changing background color of togglebutton when checked
Here is the code that should do what you want (used this topic for reference remove blue highlight on buttons wpf):
<RadioButton Content="Point">
<RadioButton.Template>
<ControlTemplate>
<ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" Background="Transparent">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="border" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>

Related

WPF - Change button templated text color on DataTrigger

I have a button that has a control template set (including some controltemplate triggers), and I want to change its text color upon a DataTrigger. I've read that I cannot access the TargetName ("theContent") of the template as it has its own scope, so how can I achieve this?
<Button BorderThickness="0" MaxWidth="94" Height="26" Margin="1,0,0,0">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="theBorder" CornerRadius="15" BorderThickness="0" Background="{TemplateBinding Background}">
<Label x:Name="theContent" VerticalContentAlignment="Center" Foreground="White" FontWeight="Bold">
<TextBlock Text="..." TextTrimming="CharacterEllipsis"></TextBlock>
</Label>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="#1A65AF"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#4d87c0"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#004b95"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{...}" Value="..."></Condition>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="False"></Condition>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="#ad4811"/>
<Setter Property="Foreground" Value="#7F7F7F" /> // does nothing
<Setter TargetName="theContent" Property="Foreground" Value="#7F7F7F" /> // target not found
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<!--<Button.Content>
<Label x:Name="theContent" VerticalContentAlignment="Center" Foreground="White" FontWeight="Bold">
<TextBlock Text="..." TextTrimming="CharacterEllipsis"></TextBlock>
</Label>
</Button.Content>-->
</Button>
The 2 setters that I tried and don't work are these:
<Setter Property="Foreground" Value="#7F7F7F" /> // does nothing
<Setter TargetName="theContent" Property="Foreground" Value="#7F7F7F" /> // target not found
In your control template, you just need to use TemplateBinding rather than hardcoding the value to White.
<Border x:Name="theBorder" CornerRadius="15" BorderThickness="0" Background="{TemplateBinding Background}">
<Label x:Name="theContent" VerticalContentAlignment="Center" Foreground="{TemplateBinding Foreground}" FontWeight="Bold">
<TextBlock Text="..." TextTrimming="CharacterEllipsis"></TextBlock>
</Label>
</Border>
Doing that will defer to the button Foreground property. Generally, if any properties need to change in your ControlTemplate dynamically, you will want to use TemplateBinding (for example the FontWeight property). Now your StyleTrigger setter will work as expected.
Btw, Foreground="{TemplateBinding Foreground}" is just shorthand for
Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"

How to align the first TabItem with the left border of its TabControl?

I'm working on a custom TabControl for my C#-WPF-application. Basically, everything I want works just fine. Except for one litte thing that really annoys me: The first TabItem of the TabControl is indentet 2 pixels and therefore won't align with the left border of the TabControl. Unfortunately I can't yet post pictures, so I hope you guys get what I mean...
So, is there any possibility to get the first TabItem aligned with its TabControl? Maybe by somehow setting its position?
Here's the entire XAML-code:
<UserControl x:Class="DocumentationOfXmlInterfaces.CentralTabControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl
Name="MyTabcontrol"
BorderBrush="Navy"
BorderThickness="2"
ItemsSource="{Binding}"
SelectionChanged="MyTabcontrol_SelectionChanged"
>
<TabControl.Resources>
<Style TargetType="TabPanel">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
ClipToBounds="True"
>
<Border
x:Name="MyBorder"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Navy"
BorderThickness="1"
>
<DockPanel
Name="MyDockpanel_Content"
>
<ContentPresenter
x:Name="MyContentPresenter"
HorizontalAlignment="Center"
Content="{TemplateBinding Content}"
/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="RoyalBlue"
/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="White"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="TabHeader" DataType="TabItem">
<DockPanel>
<Button
Name="MyButton_CloseTab"
DockPanel.Dock="Right"
Margin="10,1,1,0"
Click="MyButton_Click"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}"
>
<Image Name="MyImage_Button" Source="Icons/Close.png" Height="12" Width="12"/>
</Button>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}"/>
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Hidden"
/>
<Setter
TargetName="MyImage_Button"
Property="Source"
Value="Icons/Close2.png"
/>
<Setter
TargetName="MyImage_Button"
Property="Height"
Value="12"
/>
<Setter
TargetName="MyImage_Button"
Property="Width"
Value="12"
/>
</DataTrigger>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsMouseOver}"
Value="True"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Visible"
/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border
x:Name="MyBorder"
BorderBrush="Navy"
BorderThickness="1,1,1,0"
>
<Grid Name="Panel">
<ContentPresenter
x:Name="ContentSite"
ContentSource="Header"
Margin="5,0,0,0"
/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="Navy"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="RoyalBlue"/>
<Setter TargetName="MyBorder" Property="BorderBrush" Value="RoyalBlue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyBorder" Property="BorderBrush" Value="Navy"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid">
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
</Style>
</TabControl.Resources>
</TabControl>
I'd really appreciate your help!
Thanks! :)
Your problem here is that the headers TabPanel inside the TabControl template has its Margin set explicitly, and your Style won't be able to override it.
You may need to modify the whole TabControl's Template to change the value of that Margin.
So maybe it'd be easier to just do the negative margin trick :P
In the same mindset as this answer (Change GroupBox Header location), you could have a negative left margin on your tab item. Like this: Margin="-2,0,0,0"

DataTrigger not changing template in ItemContainerStyle for Listbox

my idea is to change appearance of ListboxItem when MouseOver or Button is clicked etc.
<ListBox Name="listbox"
Height="250"
Grid.Row="4"
Grid.ColumnSpan="5"
HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Template"
Value="{StaticResource control_mouseover}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Template"
Value="{StaticResource control_not_mouseover}" />
</Trigger>
<DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}"
Value="True">
<Setter Property="Template"
Value="{StaticResource control_mouseover}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Only for events IsMouseOver it works but DataTrigger does not seem to work
Do you happen to know why?
<ControlTemplate x:Key="control_not_mouseover"
TargetType="ListBoxItem">
<Border BorderBrush="Transparent">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource not_mouseover}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
<ControlTemplate x:Key="control_mouseover"
TargetType="ListBoxItem">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource mouseover}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" />
</ControlTemplate>
<StackPanel>
<Grid Name="grid"
Height="240">
<Button Name="Artykuły"
Grid.Column="0"
Content="{Binding Path=liczba_wpisow, Converter={StaticResource wpisy_converter}}" /> [...]
</Grid>
<Listbox... />
</StackPanel>
I see a number of problems with your code. The first is that you don't need to add a Trigger for both true and false conditions. Instead, you should do this:
<ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</Trigger>
<DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
However, this should not cause an actual error.
The second problem is that the ElementName property show be set to the actual name of the relevant control and not to the type and name:
<DataTrigger Binding="{Binding ElementName=Artykuły, Path=IsPressed}" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</DataTrigger>
UPDATE >>>
To permanently apply your Template rather than just having it when the Button is pressed, just remove the DataTrigger and move the Setter out of the Triggers collection:
<ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template" Value="{StaticResource control_mouseover}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Unfortunately, your Setter values clashed, so I had to swap them over to make it work this way, but I believe that you can re-arrange it as you see fit.
Binding="{Binding ElementName=grid.Artykuły
<Button Name="Artykuły"
-> ElementName does not match your element's Name.
Should be :
Binding="{Binding ElementName=Artykuły

wpf listbox checkbox change color when checked or selected

I have tried the different examples on this site to get the list box / check box combo to change from the default gray when selected to another color to no avail.
What I am trying to do in the end is if the item is checked, the background will be white, and when unchecked it will gray out.
Here is what I have and any help would be appreciated.
Update the resource to the comment below.
The control has been updated to the reply and still not working, any ideas?
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding}"
Name="lstSwimLane" SelectionMode="Multiple"
Width="auto"
Height="auto"
Background="Transparent"
BorderThickness="0"
SelectionChanged="LstSwimLaneSelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding Path=IsChecked, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource UnselectedBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="3,3,3,3">
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
Checked="ChkFilterChecked"
Unchecked="ChkFilterUnchecked"
VerticalAlignment="Center"
Margin="0,0,4,0" />
<TextBlock Text="{Binding Value}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Note: The checked checkboxes and list item combination is still gray and the unchecked is white.
Attached is a screen shot which seems to match the reply have below. I am stumped.
Here is the direct link in order to see the image bigger.
http://s1120.photobucket.com/albums/l489/nitefrog/?action=view&current=jw_0012011-03-311325.jpg
Here is the screen shot of the checkboxes.
http://i1120.photobucket.com/albums/l489/nitefrog/jw_0022011-03-311345.jpg
Even though the brushes are set, for some reason they are not being triggered.
Any ideas?
Thanks.
My example doesn't use the myListboxStyle style, you can remove it. But change the ItemContainerStyle property:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding Path=IsChecked, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource UnselectedBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
It is very simple template and it has only two triggers: IsSelected=True and IsSelected=False.
And to complete this example add these brushes to the Resources collection:
<SolidColorBrush x:Key="SelectedBrush" Color="White"/>
<SolidColorBrush x:Key="UnselectedBrush" Color="Gray"/>
It would be better to edit the standard style for the ListViewItem, but I can't find it in the internet and I don't have Expression Blend now.
Screen of the result:

WPF ControlTemplate and Binding

In the below code, MousePressImage is a dependency property of class ButtonControl.
The following Binding doesn't work. Appreciate your help in solving this issue.
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=MousePressImage}"/>
<Style TargetType="{x:Type local:ButtonControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonControl}">
<Border>
<Image x:Name="img"
Source="pack://application:,,,/Recipe_06_13;component/Resources/normal.bmp"
/>
</Border>
<!--<Border x:Name="border">
<Border.Background>
<ImageBrush x:Name="img"
ImageSource="/Recipe_06_13;component/Resources/fatal.png"/>
</Border.Background>
</Border>-->
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="img"
Property="Source"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=MousePressImage}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I create the ButtonControl like this.
<local:ButtonControl Height="48" Width="160"
MouseOverImage="pack://application:,,,/Recipe_06_13;component/Resources/Over.bmp"
MousePressImage="pack://application:,,,/Recipe_06_13;component/Resources/Press.bmp"
DisableImage=" ">
</local:ButtonControl>
Because your trigger is on a ControlTemplate, you need to be getting the MousePressImage from the control instance being templated. To do this, use TemplateBinding or (more reliably) RelativeSource TemplatedParent:
<Setter TargetName="img"
Property="Source"
Value="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=MousePressImage}" />

Resources