WPF Условное связывание.Button.IsEnabled для SelectedIndex> = 0 - PullRequest
9 голосов
/ 26 мая 2010

Я хочу связать свойство кнопок IsEnabled с условием типа myObject.SelectedIndex >= 0. Есть ли простой способ сделать это в xaml (без необходимости делать сумасшедшие вещи с какими-либо базовыми объектами)? Я действительно не видел хороший пример.

Честно говоря, хотелось бы, чтобы это было так же просто, как Flex 3 ... I.E.:

<mx:Button enabled="{dataGrid.SelectedIndex >= 0}" ...

Ответы [ 2 ]

16 голосов
/ 26 мая 2010

SelectedIndex равен -1, если ничего не выбрано, верно? Измени свою логику и используй триггер:

<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>
2 голосов
/ 24 ноября 2012

Я не нашел особенно простого в использовании способа встраивания выражения в XAML, поэтому вот что я использовал вместо этого:

BindingOperations.SetBinding(myBtn, Button.IsEnabledProperty, LambdaBinding.New(
    new Binding { Source = myObject,
                  Path = new PropertyPath(ComboBox.SelectedIndexProperty) },
    (int selectedIndex) => selectedIndex >= 0
));

Вам придется написать это на C #, например, в конструкторе окна.

Это также без проблем работает для привязок из нескольких источников:

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
));

Обратите внимание, что лямбда-тип статически типизирован, а любые ошибки типа (относительно) шумные, что помогает отследить их. Тип лямбда-возврата также учитывается; Вы можете использовать это для привязки ширины одного объекта к сложной формуле, основанной на ширине другого ...

Этот класс LambdaBinding не является встроенным; Вы должны включить файл LambdaBinding.cs .

Примечание. Жаль, что XAML не разрешает выражения. Да, я понимаю, что XAML должен быть "для дизайнеров" и свободен от этой неуловимой вещи, которую мы называем логика приложения , но над кем мы здесь шутим ... Во-первых, DataTrigger, показанный в другом ответе в основном является условным выражением, и поэтому ничем не отличается (только намного длиннее) от {Binding source.SelectedIndex >= 0}. Во-вторых, если идея проста, то выражения связывания, которые должен писать дизайнер, выходят далеко за пределы возможностей непрограммиста ... если вам нужны доказательства, рассмотрите что-то вроде этого:

{Binding RelativeSource={RelativeSource AncestorType={x:Type UIElement}, 
                                        AncestorLevel=1},
         Path=IsEnabled}
...