How to enable a control if a CheckBox is Unchecked? - wpf

I know that is possible disable a Control if the CheckBox is not checked, generally I did this:
<CheckBox x:Name="myCheckBox" />
<Button IsEnabled="{Binding ElementName=myCheckBox, Path=IsChecked}" />
this will enable the Button only if the CheckBox is checked, but there is a way in Xaml to enable the Button if the CheckBox is unchecked without create any Converter?
Pseudo code:
<CheckBox x:Name="myCheckBox" />
<Button IsEnabled="{Binding ElementName=myCheckBox, Path=IsUnChecked}" />
Best regards.

You may use the Binding with a DataTrigger:
<CheckBox x:Name="myCheckBox"/>
<Button x:Name="button">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=myCheckBox}"
Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Putting this answer to update visitors about the new syntax of DataTrigger to achieve the same. It worked for me on "Visual Studio 2015" or later.
<CheckBox x:Name="myCheckBox"/>
<Button x:Name="button">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myCheckBox, Path=IsChecked}"
Value="True">
<DataTrigger.Setters>
<!--it would make the Button in Disabled state since checkbox is in Checked state-->
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=myCheckBox, Path=IsChecked}"
Value="False">
<DataTrigger.Setters>
<!--it would make the Button in Enabled state since checkbox is in Unchecked state-->
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I hope it helps all. Thanks!

Related

Data Trigger Based on Element Activity WPF

I've got a button that is only conditionally enabled. I'd like to change the button's tooltip if the button is enabled or disabled.
<Button Name="OkButton" VerticalAlignment="Center" Command="{Binding Path=OkCommand}"
CommandParameter="{Binding}" Click="OkButtonClick" Content="OK">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="ToolTipService.ShowOnDisabled" Value="True" />
<Setter Property="ToolTip" Value="OK" />
<Style.Triggers>
<DataTrigger ***SomeCondition*** Value="False">
<Setter Property="ToolTip" Value="OK Disabled" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I know that I can probably bind to some property in my view model, but I would like to know if there's a way to handle this all in XAML.
it can be Trigger, not DataTrigger:
<Trigger Property="IsEnabled" Value="False">
<Setter Property="ToolTip" Value="OK Disabled" />
</Trigger>

'The member "Opacity" is not recognized or is not accessible.' Why can't I set the opacity?

I would like to use a DataTrigger to modify the opacity of my button.
<Button x:Name="StartTreatment"
Grid.Column="3"
Width="160"
Height="30"
Content="{x:Static resources:UserMessages.TrcsConsoleViewModel_LoadWfSequence_StartProcedure}"
IsEnabled="{Binding CanStartProcedure}"
Visibility="{Binding CanStartPatientTreatment, Converter={StaticResource BooleanToVisibility}}" >
<Button.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding CanStartProcedure}" Value="False">
<Setter Property="Opacity" Value="0.5"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I know that a Button has an Opacity you can set, and that DataTriggers must be used in a Style. However the compiler is reporting 'The member "Opacity" is not recognized or is not accessible.' What am I doing wrong?
You should add TargetType:
...
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding CanStartProcedure}" Value="False">
<Setter Property="Opacity" Value="0.5"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
...

WPF RelativeSource issue with nested controls

I have the following markup:
<Button Name="m_SaveButton" Command="{Binding SaveCommand}">
<StackPanel>
<Image Source="{StaticResource IconSave16}">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}}" Value="False">
<Setter Property="Source" Value="{StaticResource IconSaveInactive16}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label Content="Save" />
</StackPanel>
</Button>
I want to change the Image nested inside the Button when Button.IsEnabled is false. The markup above is not working.
I was trying to use Meleak's code found here: WPF Mouseover Trigger Effect for Child Controls
Does anyone can suggest me a solution for this?
Thank you in advance!
You can't change a local value in style because of Value Precedence. This should work.
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="{StaticResource IconSave16}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}}" Value="False">
<Setter Property="Source" Value="{StaticResource IconSaveInactive16}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

using a trigger to set a button IsEnabled to be true on mouse over

I am trying to set a button so only when a mouse is going over it the
button will change his visual properties to an enabled button.
This is my code:
<Button Foreground="Black" Content="OK" Margin="186,100,170,172" >
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEnabled" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Thanks in advance for your help.
You could encapsulate your Button in a Border to get what you're after
<Border Name="buttonBorder" Margin="186,100,170,172"
Background="#01000000" BorderBrush="Transparent" BorderThickness="0">
<Button Foreground="Black" Content="OK">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=buttonBorder, Path=IsMouseOver}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Border>
I don't think it's possible what you want to do here, because while the button is disabled, IsMouseOver is false (also, it doesn't generate MouseMove or other events).
To achieve what you want (btw, why would you want a disabled button to become enabled when you put the mouse over it? It's so unnatural... how about if you want to navigate with the keyboard to the button? it will be impossible if it is disabled), you should restyle the button and make it look as in its disabled state when the mouse is not over it and as in its enabled state when the mouse is over it - but this will require some work).

Problem with DataTrigger binding - setters are not being called

I have a Command bound to a Button in XAML. When executed, the command changes a property value on the underlying DataContext. I would like the button's Content to reflect the new value of the property.
This works*:
<Button Command="{x:Static Member=local:MyCommands.TestCommand}"
Content="{Binding Path=TestProperty, Mode=OneWay}" />
But this doesn't:
<Button Command="{x:Static Member=local:MyCommands.TestCommand}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TestProperty, Mode=OneWay}" Value="True">
<DataTrigger.Setters>
<Setter Property="Content" Value="Yes"/>
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding Path=TestProperty, Mode=OneWay}" Value="False">
<DataTrigger.Setters>
<Setter Property="Content" Value="No"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Why is that?
* By "works" I mean the Content gets updated whenever I click the button. I don't know if it's important or not, but just in case it is, I'm using .NET 3.5 SP1.
UPDATE:
I also tried another variation (removing the second DataTrigger in favor of default value), still to no avail:
<Button Command="{x:Static Member=local:MyCommands.TestCommand}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Content" Value="No"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TestProperty, Mode=OneWay}" Value="True">
<DataTrigger.Setters>
<Setter Property="Content" Value="Yes"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
TIA
Try to set your default Content to No and to use only the first DataTrigger. Avoid the second one.
I solved the problem myself. It turned out I was looking in the wrong place. The bound CLR property was of different type than what I'd assumed in XAML. My stupidity, really.

Resources