Overlapping elements and a RadioButton - c#

I want to create a RadioButton with text inside, and when checked, it needs to turn red.
How would I create this in WPF XAML?
Something like this:

In order to change the appearance of controls, you have to edit their control template. The easiest way is to extract the default style (with its control template) in Visual Studio or Blend. From there, you can adapt it to your requirements. This is an example that - although not with pretty colors - should do what you want.
<SolidColorBrush x:Key="RadioButton.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="RadioButton.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="RadioButton.MouseOver.Background" Color="#995555"/>
<SolidColorBrush x:Key="RadioButton.MouseOver.Border" Color="#990000"/>
<SolidColorBrush x:Key="RadioButton.MouseOver.Foreground" Color="#FFFFFF"/>
<SolidColorBrush x:Key="RadioButton.IsChecked.Background" Color="#FF0000"/>
<SolidColorBrush x:Key="RadioButton.IsChecked.Border" Color="#990000"/>
<SolidColorBrush x:Key="RadioButton.IsChecked.Foreground" Color="#FFFFFF"/>
<SolidColorBrush x:Key="RadioButton.IsUnchecked.Background" Color="#FFFFFF"/>
<SolidColorBrush x:Key="RadioButton.IsUnchecked.Border" Color="#990000"/>
<SolidColorBrush x:Key="RadioButton.IsUnchecked.Foreground" Color="#000000"/>
<SolidColorBrush x:Key="RadioButton.Pressed.Background" Color="#993333"/>
<SolidColorBrush x:Key="RadioButton.Pressed.Border" Color="#990000"/>
<SolidColorBrush x:Key="RadioButton.Pressed.Foreground" Color="#FFFFFF"/>
<SolidColorBrush x:Key="RadioButton.Disabled.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="RadioButton.Disabled.Border" Color="#555555"/>
<SolidColorBrush x:Key="RadioButton.Disabled.Foreground" Color="#999999"/>
<Style x:Key="MyRadioButtonStyle" TargetType="{x:Type RadioButton}">
<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="HorizontalAlignment" Value="Left"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Background" Value="{StaticResource RadioButton.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource RadioButton.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 RadioButton}">
<Border x:Name="templateRoot" Focusable="True" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Margin}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<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="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource RadioButton.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource RadioButton.MouseOver.Border}"/>
<Setter Property="Foreground" Value="{StaticResource RadioButton.MouseOver.Foreground}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource RadioButton.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource RadioButton.Disabled.Border}"/>
<Setter Property="Foreground" Value="{StaticResource RadioButton.Disabled.Foreground}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource RadioButton.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource RadioButton.Pressed.Border}"/>
<Setter Property="Foreground" Value="{StaticResource RadioButton.Pressed.Foreground}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource RadioButton.IsChecked.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource RadioButton.IsChecked.Border}"/>
<Setter Property="Foreground" Value="{StaticResource RadioButton.IsChecked.Foreground}"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource RadioButton.IsUnchecked.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource RadioButton.IsUnchecked.Border}"/>
<Setter Property="Foreground" Value="{StaticResource RadioButton.IsUnchecked.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Copy the style and the resources to any resource dictionary in scope of the control that you want to style and reference the style using StaticResource (or DynamicResource if you intend to change it at runtime).
<RadioButton Style="{DynamicResource MyRadioButtonStyle}" GroupName="MyGroupName" Content="First"/>
If you want it to be applied automatically within the resource scope, remove the x:Key to make it a so-called implicit style. Since you specifically asked for a RadioButton style, I guess there are multiple exclusive options. If there are no exclusive options, mabe a Checkbox or a ToggleButton would be a better fit, you decide. Templating those controls would be done the same way: Extract, adapt, use and have fun.

Related

Changing Foreground for IsMouseOver anf IsPressed is not working in custom style

No matter what I try I can't set get the trigger IsMouseOver and IsPressed to change the Foreground.
I have been trying to alter it in the Button itself.
<Button (STUFF HERE)>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Button>
I have been trying to look it up, but I am pretty amateur with XAML.
here the general layout for styling controls:
<Button Content="OK">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers >
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
If you want to reuse the style, then save it to a resourcedictionary as a named style and you can refer to it on your controls
You have to create a style where you put the Triggers. Add this style to any resource dictionary in scope, e.g. the Window.Resources or the application resources if you want to reuse it across the application. If you omit the x:Key, you make it implicit and therefore apply to all Buttons in scope.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
Then reference that style in the Button.
<Button Style="{StaticResource MyButtonStyle}" .../>
Alternatively, you could also directly assign the style to the Button if it is the only one.
<Button Content="Styled">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Note that while this works for the Foreground property, it does not for properties like Background as they are defined in the ControlTemplate triggers which take precedence over a style. In order change those, you have to copy and adapt the Button ControlTemplate.
Update for your comment. Maybe you understand the Foreground property wrong. It is used for the text color of the content, not the color of the button itself. The "blue-ish" tint is determined by the Background property and as stated above, you have to edit the ControlTemplate for that.
<Style x:Key="FocusVisual">
<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>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FF373737"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FF4D4D4E"/>
<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 x:Key="ButtonStyle" 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" 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>
<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>
</Style>

How to stop Flashing WPF button on Windows 7

Problem is this annoying flashing:
Yes, I know this has been answer before, but none of the answers work for me except making the button non Focusable (Focusable = false), which is not something I intend to do.
I tried setting the "FocusVisualStyle" to null, both in template, both in the specific button. Didn't work.
I have the following (based on) style for buttons:
<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 x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> <!- tried x:Null, tried removing alltogether -->
<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>
</Style>
I set style for window:
<Style TargetType="Button" BasedOn="{StaticResource ButtonStyle1}"/>
I have the following button:
<Button FontSize="18" Margin="5" Background="{StaticResource JITB.SolidColors.Open}" IsEnabled="{Binding IsEnabledSelected}" Command="{Binding DoOpenBackupFile}" Height="40">
<DockPanel >
<TextBlock Style="{StaticResource CustomFont}" Text="S " Foreground="White" Margin="0,-6,0,0"></TextBlock>
<TextBlock Margin="0" DockPanel.Dock="Top" Text="{x:Static p:Resources.MWTab2OpenBtn}" Foreground="White" VerticalAlignment="Center"/>
</DockPanel>
</Button>
(I tried setting "FocusVisualStyle" to null also in the dockpanel... )

WPF ToggleButton display state when disabled

I have toggle buttons on a WPF form that I use to display boolean value.
Some of those button are supposed to be "read only", so I setted them with IsEnabled = false.
However, those should display their IsChecked state nonetheless but they all apear as unchecked
As you can see, all the disabled seem unchecked, where some should look checked.
I'm creating the toggle buttons by code but the problem is there too with "static" toggle buttons
ToggleButton tb = new ToggleButton();
tb.Name = "btnRegisterR" + register + "P" + pos;
tb.Content = tuple.Item1";
tb.IsChecked = rnd.NextDouble() >= 0.5;
tb.IsEnabled = tuple.Item2;
tb.VerticalAlignment = VerticalAlignment.Top;
tb.HorizontalAlignment = HorizontalAlignment.Left;
tb.Height = 25;
tb.Width = 87;
tb.Margin = new Thickness(xPos, yPos, 0, 0);
registerGrid.Children.Add(tb);
Edit : I don't think this is a duplicate of the linked question, as I'm not looking so much to disable interaction on the button as for it to look disabled but keep displaying its status. The linked question only answer the functional part wheras i'm asking mostly about the styling part.
For exemple, in Winforms, there was the apperance button for a checkbox, which allow 2 separate display states (by default a gray button when unselected/unchecked and a light blue one when selected/checked).
On top of that, the control could be enabled/disabled, which, in its disable state, would whitend the whole control but still display diferrently when enabled or disabled.
Edit 2 : For futher clarification, here is what I was using in an old Winform App with checkboxes with an appearance setting set to "button"
You can clearly visualy separate the ones that are enabled or disabled while still be able to see the state of the input (checked or not). I'm just trying to replicate this display behavior in WPF, without succes for the moment as the "Checked|Disabled" and the "Unchecked|Disabled" look exactly the same with the WPF toggle button.
Edit 3 :
I ended up using multitrigger in the style to make it work. don't know if it's the best solution, but, at least, it give the same results as in winform
<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>
</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"/>
<Style x:Key="disabledAndCheckedButton" TargetType="{x:Type ToggleButton}">
<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 ToggleButton}">
<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="Button.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="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False" />
<Condition Property="IsEnabled" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<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}"/>
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="IsEnabled" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I just tried to solve your problem and you can do it by setting the tb.IsHitTestVisible=false; but leave IsEnabled=true.
This will allow the Button to retain it's visual state but it will disable any interaction with it.
Treat it as a IsReadOnly.
EDIT:
After long think I went ahead and used Blend to create Style for your Button:
<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>
</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"/>
<Style x:Key="disabledAndCheckedButton" TargetType="{x:Type ToggleButton}">
<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 ToggleButton}">
<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="Button.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="IsChecked" 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>
</Style>
This bit of code would go into your App.xaml file where you can reference it anywhere in your app.
You would use this piece as follows:
<ToggleButton Content="{Binding .}" Style="{StaticResource disabledAndCheckedButton}"/>
And if you want to keep the code-behind
(not cool bro)
then use this snippet where you programatically generate buttons:
Style style = this.FindResource("disabledAndCheckedButton") as Style;
tb.Style = style;
Let us know if you need any help.

change button background when mouse is over the button

I wanted to change button mousover color , When i could't to change it , I decided to change the background
I use this code but it doesn't work
<Button Name="btnClose" IsHitTestVisible="False">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="30"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I use this in usercontrol
Thank you for answer
For some elements you cannot just change properties in the style. Button is one of them. You really need to change the whole template.
Easiest way is to right click on your button and select Edit Template >> Edit a copy:
This will create you a new Style with the template which you can modify as you want:
<Window.Resources>
<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>
</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"/>
<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="Red"/> <!--HERE-->
<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>
</Style>
</Window.Resources>
The IsHitTestVisible property is causing trouble. Its used only when you are making your own composite controls and don't want some parts to respond on interaction.
Your working XAML should be like
<Button Name="btnClose">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="30"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

WPF: Cant find correct BorderBrush after setting Style

I have a button which I apply a style too. After the style is applied I have a test that checks the BorderBrush of the button to make sure the style was correctly applied. This test always fails, because the BorderBrush never gets updated in the Buttons properties.
Is there a way for me to get the actual BorderBrush being displayed? All i can get is the default BorderBrush, not the applied styles value.
The style I am using is this:
<Style x:Key="ActiveModuleBtnStyleOn" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Margin="0"
BorderThickness="3"
BorderBrush="Green"
Background="White"
VerticalAlignment="Stretch"
CornerRadius="4"
HorizontalAlignment="Stretch">
<Border.Effect>
<DropShadowEffect BlurRadius="10" Color="Black" Direction="325" Opacity=".5" RenderingBias="Quality" ShadowDepth="5" />
</Border.Effect>
</Border>
<TextBlock Margin="2" Text="{TemplateBinding Content}" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsEnabled" Value="true"/>
</Style>
Then I apply the style like this:
if(var1 == 1)
TopologyNvTxBtn.Style = this.FindResource("ActiveModuleBtnStyleOn") as Style;
else
TopologyNvTxBtn.Style = this.FindResource("ActiveModuleBtnStyleOff") as Style;
In my test app, I want to check which style has been applied. The difference between the two styles is the border brush. I would like to do something like this:
if(TopologyNvTxBtn.BorderBrush == Brushes.Green)
return PASS;
But the BorderBrush never changes (e.g. in a watch window, it stays the same as the default buttons style BorderBrush), but its definitely applied correctly as in the GUI it turns green.
How can i access this property in my test?
Many thanks in advance
The BorderBrush property of the Button is not bound to anything in your template. You need to do this in the control template:
<Style x:Key="ActiveModuleBtnStyleOn" TargetType="Button">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Margin="0"
BorderThickness="3"
BorderBrush="{TemplateBinding BorderBrush}"
Background="White"
VerticalAlignment="Stretch"
CornerRadius="4"
HorizontalAlignment="Stretch">
<Border.Effect>
<DropShadowEffect BlurRadius="10" Color="Black" Direction="325" Opacity=".5" RenderingBias="Quality" ShadowDepth="5" />
</Border.Effect>
</Border>
<TextBlock Margin="2" Text="{TemplateBinding Content}" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsEnabled" Value="true"/>
</Style>
Notice how the BorderBrush is now bound to the BorderBrush property of the Button. Then you you can set the BorderBrush in the style and should be able to access it in this way:
if(TopologyNvTxBtn.BorderBrush == Brushes.Green)
Let me know if that works.
Cheers,
Eric
As I stated above, the Border is part of the Button ControlTemplate. I just launched Blend and got a copy of the "Factory" template. With this, you can do pretty much everything with it (assuming you know about Stylying.):
<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>
</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"/>
<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>
</Style>
MSDN has a good introductory tutorial about Style and Templates. Besides, you can find tons of articles around the web!
The Button itself is pretty much this:
<Border
x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ContentPresenter
x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
So, what your looking for is Triggers, you'll have to add and change as you wish these tags:
<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>
Things to pay attention: TargetName and every <Trigger Property="IsDefaulted" Value="true"> alike!
Good luck!

Categories

Resources