How can I remove disabled effect from Radio Button? - c#

I'd like to have a Radio Button whose IsEnable property doesn't make any change in its visual appearance. However, the Radio Button shouldn't allow user to do anything when its IsEnable property is False.
I just want want to have a Radio Button which looks same irrespective of its IsEnable property. Apart from Visual appearance everything else should work as it is.
You may find it as a strangest requirement. But I want to achieve this. I'm using Radio Buttons as List Box items in List Box. Everything works good, but the problem occurs when user do Ctrl Mouse Left Click on checked Radio button. That's where everything fails.
Please help me.

You will have to extract the ControlTemplate of a RadioButton and then remove the style for Disable trigger. Below is an example of a standard template for a RadioButton. Just comment out the trigger IsEnable = False
<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="#F4F4F4"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Themes:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" IsRound="true" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Ashwin,
Its Very simple
Just follow the steps.
Right Click on the RadioButton, Edit Template and Edit a Copy
Then go to the Style created and comment out the code in storyboard of Disabled Visual state as shown in this image "http://i.stack.imgur.com/3TNoR.png"
Then it must look same for both states.
Take a look at the result "http://i.stack.imgur.com/fCL47.png"
Hope it solved your purpose.
Thanks,

Related

WPF changing button color, with a defined style already in place

i've made some rounded buttons, using a template. hovering the button changes the colour
MainWindow
<Button Grid.Column="1" x:Name="pressbtn" Command="{Binding TypeChange}"
CommandParameter="{Binding Name ,RelativeSource={RelativeSource Self}}"
Style="{StaticResource btnBlue}" BorderBrush="MidnightBlue"
HorizontalAlignment="Stretch">Press</Button>
Style Resource
<Style TargetType="Button" x:Key="btnBlue">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#000"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0,1,1,0"
CornerRadius="10">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="MidnightBlue"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
this works fine, but i'd like the button to stay on a background colour until another button is pressed, upon which it would go transparent and the other button would change colour
i have tried (where IsSelected is an integer, with each button triggering the property)
<DataTrigger Binding="{Binding IsSelected}" Value="0">
<Setter Property="Background" Value="MidnightBlue"/>
</DataTrigger>
i've also tried
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="MidnightBlue"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
it seems that any of the button events (like IsPressed) are transient, so a button press works for a brief period but wont stick. reading up about the , it appears that it doesn't work because i set the Background inline in the main Setter
<Setter Property="Background" Value="Transparent"/>
However, if i take out that Property, nothing changes
this part of XAML is a weak point (Styles, Templates), and i can't find anything in searching that helps or at least that i understand very well. Any assistance in getting the <DataTrigger> or other method to work is appreciated
If you want a "sticky" version of IsPressed, you should use a ToggleButton and bind to its IsChecked property.
An ordinary Button has no property to indicate whether it has previously been clicked or not.
You will of course also have to write some code that sets the IsChecked property back to false or true when the other Button is clicked.
If IsChecked doesn't fits your requirements, there is the Tag property that you can set to anything.

How can I change Button color via a trigger in the button?

Whats wrong with this trigger? I found it here: http://www.wpf-tutorial.com/styles/trigger-datatrigger-event-trigger/ and ive seen similar setups on SO
<Button x:Name="ColorPickerButton" Background="{Binding SelectedColor}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Im trying to break down my spaghetti XAML and make it more readable. This is my old implementation which does work. I dont like it because it overwrites the button content and overlays a border which seems unnecessary. Also its massive
<Button x:Name="ColorPickerButton" Background="{Binding SelectedColor}">
<Button.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<GridViewRowPresenter/>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{StaticResource ColorPickerButton.MouseOver.Border}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
Your Trigger does not work because the default Template of the button has its own trigger that changes the background brush of the root border when the IsMouseOver Property is set. This means: As long as the mouse is on top of the button, the Background-property of the button control will be ignored by its template.
The easiest way to check out the default style of your button is to: right-click at the button in the visual studio wpf designer. Click 'Edit template' -> 'Edit a copy' and select a location.
A copy of the default style is created at the specified location. You will see a trigger like this:
<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>
On top of designer created style definition it also created the brushes that are used within the style:
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
You can either change these brushes or the Value property of the setters above to change the background when the mouse is over.
Or you create your own Template like you did in your old implementation.

Removing border style from disabled button

I have a UserControl which contains a Button, this Button then contains an Image and a TextBlock. This enabled me to have an image button. I also want the button to have a borderless style, which I have achieved by setting the button BorderBrush to null. This part all works fine.
The problem I have is when I want to "disable" the UserControl. I can do this by settings the IsEnabled property to false, which cascades down to the button and appropriately prevents the button from being clicked. However, when the button is disabled it displays a border, which I do not want.
Question: How can I get rid of the button's border when it is disabled?
I have tried a few different methods such as setting the border from code:
MyButton.BorderBrush = Brushes.Transparent;
and using a style in the XAML:
<Button.Style>
<Style TargetType="Button">
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Style>
</Button.Style>
and a few other things just to try and get something to work, but nothing has made any difference so far.
NOTE: I have tried both above solutions with the Opacity property and both work fine in that respect, but not when I try to change the border
Unfortunately, the Style that is applied to the Button when it is disabled is applied in the default ControlTemplate. That means that if you want to change it, you'll need to define a new ControlTemplate for your Button. You can find the default ControlTemplate in the Button Styles and Templates page on MSDN.
When providing a new ControlTemplate, one sometimes misses parts from the original template, so a good starting point is to implement the default ControlTemplate as it is on that page and then 'tweak' it to your liking.
Since you already have a template for your Button you'll need to insert a Trigger with the Property="IsEnabled" Value="False":
A sample ControlTemplate for a Button:
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" TextBlock.Foreground="{StaticResource Button.Static.Foreground}" 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}"/>
<Setter Property="TextBlock.Foreground" TargetName="border" Value="{StaticResource Button.MouseOver.Foreground}" />
</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}"/>
<Setter Property="TextBlock.Foreground" TargetName="border" Value="{StaticResource Button.Pressed.Foreground}" />
</Trigger>
//Here's the code where you want to change the border
//Change the Value part to whatever you want.
<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>
Sorry about the indentation, but I believe you'll achieve what you want!

Thum not allowing to fire leftMouseDown

I am trying to implement dragdrop functionality in Listbox(with in the listbox). For dragging i am using Thumb control (Mythumb is the class inherited from thumb)
so i have set the items panel to Canves and set the style for list box item to following
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="150" />
<Setter Property="Margin" Value="5,2" />
<Setter Property="Padding" Value="3" />
<Setter Property="dcc:OutputConfigurationPanel.Left" Value="{Binding Left}"></Setter>
<Setter Property="dcc:OutputConfigurationPanel.Top" Value="{Binding Top}"></Setter>
<Setter Property="IsSelected" Value="{Binding IsSelected}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid DockPanel.Dock="Bottom" >
<Grid>
<Border BorderBrush="Black" Background="Black">
<ContentPresenter x:Name="ContentHost" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<MythumbTemplate="{StaticResource MoveThumbTemplate}" Cursor="Hand" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter Property="Background" Value="#FF233B00" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The drag drop is working fine but the thumb doesn’t allow the item to be selected. After checking i found that the mousedown event is not firing.
Is there a way to enable the select the items in usual ways?
A Thumb will always eat mouse clicks, same as button.
As I see it, you have two options:
From the code of the thumb, search up until you find the list box item and then set it's IsSelected property to true.
Scrap the thumb and create a Behavior that deals with dragging but doesn't handle mouse events (i.e. doesn't set e.Handled=true;) - this will preserve list box functionality.
Option 1 is probably faster, but I'd strongly consider to go with option 2 - less meddling with core controls functionality = better.

Proper way to override style values in WPF

I want to edit a the cell style of a DataGrid in WPF. So using Expression Blend I right go to - Objects and Timeline>>DataGrid>>Edit Additional Templates>>Edit CellStyle>>Edit a Copy
Here's what what appears on the page:
<SolidColorBrush x:Key="{x:Static DataGrid.FocusBorderBrushKey}" Color="#FF000000"/>
<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
But I only want to change the padding and background. Instead it has given me 25 lines of code, including the cell template! Am I missing something, is there a better way of styling items like this without having to bring so much extra unnecessary code when I only want to change two items?
Check out the "BasedOn" attribute for Styles...
For example the following style takes everything from DataGridColumnHeader and only overrides the HorizontalContentAlignment property:
<Style x:Key="CenterAlignedColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}"
BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
Overriding control templates in WPF requires you to completely replace the template. You may have wanted to change just the one aspect of the template but the result of that is Expression dumping a copy of the rest of the template so that it can be overridden. Make sure you're overriding the cell in the proper way (I'm not sure there's another way). Some controls (ListView comes to mind) will let you swap out data templates without overriding the entire control template, but I'm not sure that's what you want, or if it can be done with DataGrid.
See the answer to this: Replace part of default template in WPF
To do what you want to do, you would usually just set the background and Padding properties in a style:
<Style TargetType="DataGridCell">
<Setter Property="Padding" Value="10" />
<Setter Property="Background" Value="Green" />
</Style>
However in this case it seems that the default control template for DataGridCell ignores the padding value, so you will need to replace it with an implementation that doesn't. The following is based on the default template that you posted:
<Style TargetType="DataGridCell">
<Setter Property="Padding" Value="10" />
<Setter Property="Background" Value="Green" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter
Margin="{TemplateBinding Padding}" <!-- this bit does the padding -->
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Categories