How can I trigger style to ContentPresenters inside - c#

I want to trigger style to ContentPresenter's items.
How can I do it?
I have template like this. (almost default button style)
<Style x:Key="ImageButtonStyle2" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background3}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border3}"/>
<Setter Property="Foreground" Value="{StaticResource Button.Static.Foreground3}"/>
<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="{StaticResource Button.Static.Foreground3}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background3}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border3}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background3}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border3}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background3}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border3}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground3}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And, I'm using button like this.
<Button x:Name="ImageButton2" Style="{DynamicResource ImageButtonStyle2}">
<StackPanel Orientation="Vertical">
<Viewbox Width="48.000" Height="30.000">
<Canvas Width="48.000" Height="30.000">
<Path Fill="..." Data="..." />
</Canvas>
</Viewbox>
<TextBlock Text="XXX"/>
</StackPanel>
</Button>
When disabling button, I want to change the Fill, Foreground and Background color of Path and TextBlock items.
I was thinking to write a Setter tag to the Trigger "IsEnable" tag... but I'm stuck with that.
Is there any good way to do that?

If you want the same Background color of Button to reflect in your Path and TextBlock, You can Bind Background property of Button to Path's Fill and TextBlock's Foreground property.
<Button x:Name="ImageButton2" Height="30" Width="100">
<StackPanel Orientation="Vertical">
<Viewbox Width="48.000" Height="30.000">
<Canvas Width="48.000" Height="30.000">
<Path Fill="{Binding Path=Background, RelativeSource={RelativeSource AncestorType=Button}}"
Data="..." />
</Canvas>
</Viewbox>
<TextBlock Foreground="{Binding Path=Background, RelativeSource={RelativeSource AncestorType=Button}}"
Text="XXX"/>
</StackPanel>
</Button>
Or
If you are looking for different Backgroud, you can try setting Foreground using separate Triggers. Like,
<TextBlock Text="XXX">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType=Button}}"
Value="False">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

Related

how to create the blue border on checkbox when mouse is over the containing element C# WPF

I have a WrapPanel containing a Label and a CheckBox. The idea is to make the Label and the CheckBox look like 1 element, so when the WrapPanel's MouseLeftButtonUp is fired (weather the event happens on the CheckBox, or the Label), the checkbox inside it becomes checked (or unchecked if it was already checked).
In WPF, when you move your mouse over a CheckBox it gets this blue border. i want it to happen when the mouse goes over any part of the WrapPanel (the Label or the CheckBox itself)
I tried to call the myCheckbox.Focus(); when the MouseEnter for the WrapPanel is fired, but didn't do the trick.
I also saw this link on how to make checkbox focus border apear when calling CheckBox.Focus(), but it didn't answer my question either.
Any help is appreciated.
Modify the template of the CheckBox to use a WrapPanel instead of the default Grid:
<CheckBox>
<TextBlock>Label that wraps with the CheckBox...</TextBlock>
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Style.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<WrapPanel x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid">
<Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph}" Margin="1" Opacity="0" Stretch="None"/>
<Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph}" Margin="2" Opacity="0"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</WrapPanel>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Opacity" TargetName="optionMark" Value="0"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
If you're open to an alternative (simpler) solution, This is how you should do it: define a custom style for the checkbox and override the Template so to get the WrapPanel and whatever controls you want look as part of the CheckBox..
<Style TargetType="{x:Type CheckBox}" x:Key="myCheckboxStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<WrapPanel>
<Label />
<!-- other Controls -->
<ContentPresenter/>
</WrapPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Apply the custom style to the checkbox
<CheckBox Style="{StaticResource myCheckboxStyle}" Content="Check Me"/>

How to disable a button and change it's color?

I have this code I found on here, that generates me a grid of buttons - I know this may not be the best way to do this, but for now I'd like to do it this way, I am quite new at this. So the button should be either Black(1) or White(0), depending on it's value. This all works, until I hover the button and I can see it's value. If I just add the Visibility property = "false" to the button, it does not even get displayed.
This is my code:
<Window.Resources>
<DataTemplate x:Key="DataTemplate_Level2">
<Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="1">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="0">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_Level1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_Level2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
And then I display the grid here:
<Grid Margin="10,10,10,-636" Grid.Row="3">
<ItemsControl x:Name="automata" ItemTemplate="{DynamicResource DataTemplate_Level1}" Margin="0,0,0,-119"/>
</Grid>
I would also be happy of a recommendation on how to display these values in another way.
If you want to change the appearance or visual states of a control, create a style with a ControlTemplate that fits your requirements. You can also extract the default style using Blen or Visual Studio and adapt it.
In the following, I took the default style with its control template for Button and commented out the triggers for MouseOver, Pressed and other states so they are ineffective, but you still see where to continue since your question certainly is only the starting point for further customization. I adapted and added your triggers to the ControlTemplate. What this does is simply show a black button for 1 and white for 0.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Style.Resources>
<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"/>
</Style.Resources>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<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" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" 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>
<!-- These are the default triggers, which you might customize to fit your style. -->
<!--<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>-->
<!-- These are your triggers, which now act on the Content property of the templated button. -->
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="1">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="0">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use this style in your data template and you should get the expected result.
<DataTemplate x:Key="DataTemplate_Level2">
<Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyButtonStyle}"/>
</DataTemplate>
Since you try to make the text 1 and 0 invisible by setting the background and foreground to the same color, you could also simply remove the ContentPresenter from the ControlTemplate, so there is no content displayed at all and the Foreground setters are not needed.
Another thing to note is that your binary state maybe suggests to use a ToggleButton instead.
Base class for controls that can switch states, such as CheckBox.
This is an example style for a ToggleButton that does not show content and sets the background like in your question, but dependening on its IsChecked property.
<Style x:Key="MyToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Style.Resources>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
</Style.Resources>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<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 ToggleButton}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Black"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change the binding in your data template from Content to IsChecked.
<DataTemplate x:Key="DataTemplate_Level2">
<ToggleButton IsChecked="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyToggleButtonStyle}"/>
</DataTemplate>
This buys you the advantage of toggling the states automatically, but only if you can provide a property for two-way binding (getter and setter), otherwise an exception will be thrown.

Change Path Fill inside radio button WPF C#

I read on internet that to make a custom style of radio button you need to create a toggle button style.
So here my style :
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Focusable" Value="False" />
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainOrangeBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainOrangeBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Background" Value="{StaticResource DisableGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainWhiteBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton Content="{Binding Path=(Content), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RadioButton}}}" IsChecked="{Binding Path=(IsChecked), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RadioButton}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I still don't fully understand ContentTemplate and ContentPresenter. I understand that the content presenter is for everything inside the UI element.
So my problem is that I want to set the fill the same color as the foreground inside the toggle button:
<RadioButton
x:Name="Btn"
Width="40"
Height="40"
HorizontalAlignment="Right"
IsChecked="{Binding IsChecked}"
ToolTip="Btn">
<Path
Width="30"
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"
Stretch="Uniform" />
</RadioButton>
This line does not work :
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"
Can you help?
I read on internet that to make a custom style of radio button you need to create a toggle button style.
No. You have to create a style for the type RadioButton. The RelativeSource binding does not work, because it does not search for ancestors within the control template and will therefore not find the ToggleButton.
In order to solve your issue, you should create an appropriate style for RadioButton. It is not necessary to use a toggle button in it, but even if you would, the triggers would be defined in the control template, too. Moreover, the style for the ToggleButton as you have defined it is implicit (without an x:Key), which causes it to be applied to every toggle button in scope, not just the RadioButton and that is not what you want.
I have created a sample style that might look similar to what your are trying to do.
<Style x:Key="FocusVisual1">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual1">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
<Setter Property="Background" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Focusable" Value="False" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="radioButtonBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid" Margin="2">
<Path x:Name="optionMark"
MinHeight="6"
MinWidth="6"
Margin="2"
Opacity="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
Fill="{TemplateBinding Foreground}"
Stretch="Uniform" />
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainOrangeBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource DisableGrayBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainDarkerGrayBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainOrangeBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Opacity" TargetName="optionMark" Value="0.56"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The result looks like below. It is still a radio button, but with your custom Path as option mark and your custom colors applied to the respective states.
In this example, the Path is embedded in the control template and the Content, here the text Test is still applied. You can of course further customize the template so that it fits your requirements.
If you want the Content and the option mark to be customizable without creating a different style, you will have to create a custom radio button control derived from RadioButton and expose a dependency property to specify the option mark content. Then you can bind it in the control template, but that is another question.

WPF ListBox turn off hover effect

I've found and tried many solutions on the internet which should allow me to disable the hover effect of my WPF ListBox but none of them seemed to work for me. This screenshot shows the hover effect I'd like to hide or get rid of:
This is (a simplified version) of the XAML code I currently have:
<ListBox ItemsSource="{Binding Logs}" Grid.Column="1" Width="800" Height="100" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
However, it doesn't seem to work for me for a reason or another. Could my parent ListBox (the one in the background) or another control override it's child's style by any chance? (I already tried to override the parents style as well)
Modify the default style of a ListBoxItem
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Just add a trigger
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
Getting rid of the blue devil?
If you have no need to click on your items the following will make it disappear, the highlighting on mouse hover:
<ListBox IsHitTestVisible="False">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsTabStop" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Glad that" />
<ListBoxItem Content="they are over" />
<ListBoxItem Content="the days of the blue devil" />
</ListBox>

Styling ListView(for custom template) WPF

I have few questions about styling ListView. For example I have some style:
<Style x:Key="MyListView" TargetType="{x:Type ListView}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Border x:Name="PART_ControlBorder" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="0">
<Grid>
<ScrollViewer Grid.Row="1"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden"
CanKeyboardScroll="False"
Padding="{TemplateBinding Padding}"
Focusable="false">
<ItemsPresenter x:Name="PART_ItemsPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="ItemBorder" CornerRadius="4" SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="2" Padding="1">
<Grid>
<TextBlock Text="{Binding Key}" Background="LightGray"/>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
Why are setters for Backgroud and BorderBrush not working(ItemContainerStyle)? I had to hide selection using redefinition for system Brushes, but its wrong way:
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00000000"/>
How could I set BorderBrush for ItemBorder (on mouseOver event)?
How could I set BorderBrush for ItemBorder(only for selected Items)?
What shall I do to change default selection style?
I'd found answer by myself.
To set style for ItemBorder I had to create few DataTriggers and put them into DataTemplate:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListViewItem}},Path=IsSelected}" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="Lime"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListViewItem}}, Path=IsMouseOver}" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="Orange"/>
</DataTrigger>
</DataTemplate.Triggers>
About question 1 and 4 I still haven't answer...(If I won't count way to change default system brushes)

Categories