I want to bind a buttons IsEnabled
property to a condition like myObject.SelectedIndex >= 0
. Is there a simple way to do this in the xaml (without having to do crazy things to any underlying objects)? I haven't really seen a good example.
Honestly, I wish this was as easy as Flex 3 ... I.E.:
<mx:Button enabled="{dataGrid.SelectedIndex >= 0}" ...
SelectedIndex is -1 if nothing's selected, right? Reverse your logic and use a trigger:
<Button ...>
<Button.Style>
<Style TargetType="Button">
<Setter Property="enabled" Value="True" />
<Style.Triggers>
<DataTrigger
Binding="{Binding SelectedIndex,ElementName=dataGrid}"
Value="-1">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
<Button.Style>
<Button>
I haven't found a particularly easy-to-use way to embed an expression into XAML, so here's what I've been using instead:
BindingOperations.SetBinding(myBtn, Button.IsEnabledProperty, LambdaBinding.New(
new Binding { Source = myObject,
Path = new PropertyPath(ComboBox.SelectedIndexProperty) },
(int selectedIndex) => selectedIndex >= 0
));
You'll have to write this in C#, for example in the window's constructor.
This also works seamlessly for multi-sourced bindings:
BindingOperations.SetBinding(myBtn, Button.IsEnabledProperty, LambdaBinding.New(
new Binding { Source = myObject,
Path = new PropertyPath(ComboBox.SelectedIndexProperty) },
new Binding { Source = myObject2,
Path = new PropertyPath(Button.ActualHeightProperty) },
(int selectedIndex, double height) => selectedIndex >= 0 && height > 10.5
));
Observe that the lambda is statically typed, and any type errors are (relatively) noisy, helping track them down. The lambda return type is also taken into account; you could use this to bind the width of one object to be a complex formula based on the width of another one...
This LambdaBinding
class isn't built-in; you have to include the LambdaBinding.cs file.
Side note. It's a real shame that XAML doesn't allow expressions. Yes, I realise XAML is supposed to be "for designers" and free of this elusive thing we call application logic, but who are we kidding here... Firstly, the DataTrigger
shown in the other answer is basically a conditional expression, and so no different (only much longer) than {Binding source.SelectedIndex >= 0}
. Secondly, if the idea is simplicity, then the binding expressions that a designer is supposed to be able to write are far beyond the abilities of a non-programmer... if you need proof, consider something like this:
{Binding RelativeSource={RelativeSource AncestorType={x:Type UIElement},
AncestorLevel=1},
Path=IsEnabled}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With