What I have is an object with the IsReadOnly property. If this property is true, I want to set the IsEnabled property on the Button (for example) to false.
I want to believe that I can do this as easily as isenabled '{binding path =! IsReadOnly}', but it doesn't apply to WPF.
Do I have to go through all the style settings? It seems too long for something as simple as setting one bool to the opposite of another.
<Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True"> <Setter Property="IsEnabled" Value="False" /> </DataTrigger> <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style>
#1 building
You can use ValueConverter to reverse the bool property for you.
XAML:
IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"
Converter:
[ValueConversion(typeof(bool), typeof(bool))] public class InverseBooleanConverter: IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (targetType != typeof(bool)) throw new InvalidOperationException("The target must be a boolean"); return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } #endregion }
#2 building
Have you considered the IsNotReadOnly property? Additional properties make sense if the bound object is a ViewModel in the MVVM domain. If it is a direct entity model, you can consider combining and rendering the entity's dedicated ViewModel to the form.
#3 building
I suggest using https://quickconverter.codeplex.com/
Then reverse the Boolean as simple as this: < button isenabled = "{QC: binding '! $p', P = {binding isReadOnly}" / >
This speeds up the time it usually takes to write a converter.
#4 building
With standard binding, you need to use a converter that looks windy. Therefore, I suggest you view my project CalcBinding , which was developed specifically to solve this problem. With advanced binding, you can write expressions with many source properties directly in xaml. Say, you can write:
<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />
Or
<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>
Or
<Label Content="{c:Binding A+B+C }" />
Or
<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
Where A, B, C, ischecked - properties of the ViewModel, which will work properly
Good luck!
#5 building
I don't know if this is related to XAML, but in my simple Windows application, I manually created a binding and added a Format event handler.
public FormMain() { InitializeComponent(); Binding argBinding = new Binding("Enabled", uxCheckBoxArgsNull, "Checked", false, DataSourceUpdateMode.OnPropertyChanged); argBinding.Format += new ConvertEventHandler(Binding_Format_BooleanInverse); uxTextBoxArgs.DataBindings.Add(argBinding); } void Binding_Format_BooleanInverse(object sender, ConvertEventArgs e) { bool boolValue = (bool)e.Value; e.Value = !boolValue; }