开发者

WPF Conditional Binding. Button.IsEnabled to SelectedIndex >= 0

开发者 https://www.devze.com 2022-12-31 20:50 出处:网络
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 object

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="{dataGri开发者_高级运维d.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}
0

精彩评论

暂无评论...
验证码 换一张
取 消