2010-05-26 3 views
9

Chcę powiązać właściwość przycisków IsEnabled z warunkiem takim jak myObject.SelectedIndex >= 0. Czy istnieje prosty sposób na zrobienie tego w Xaml (bez konieczności szalonych rzeczy do jakichkolwiek obiektów leżących pod spodem)? Tak naprawdę nie widziałem dobrego przykładu.Wiązanie warunkowe WPF. Button.IsEnabled na SelectedIndex> = 0

Szczerze życzę było to tak proste, jak Flex 3 ... tj .:

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

Odpowiedz

16

SelectedIndex jest -1 jeśli jest zaznaczona nic, prawda? Odwrócenie logiki i użyć wyzwalacza:

<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> 
+0

Dzięki, mogę użyć tego dla jednego z moich przycisków, ale drugi będzie tam, gdzie SelectedIndex> = 1. Czy mogę zrobić to jak twój przykład powyżej, ale tylko z MultiDataTrigger? –

+1

MultiDataTrigger jest używany, gdy warunki są połączone razem. Aby wykonać SelectedIndex> = 1, skopiuj datatrigger dla "-1" i zmień wartość wyzwalania na "0". –

2

nie znalazłem szczególnie łatwy w obsłudze sposób, aby umieścić wyrażenie do XAML, więc oto co używam zamiast:

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

Będziesz musiał napisać to w języku C#, na przykład w konstruktorze okna.

To działa również bezproblemowo dla wielo-pozyskiwane wiązań:

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

Zauważ, że lambda jest statycznie wpisane, a wszelkie błędy typu są (względnie) hałaśliwe, pomaga śledzić je w dół. Uwzględniany jest również typ powrotu lambda; można go użyć do powiązania szerokości jednego obiektu jako złożonej formuły opartej na szerokości innego ...

Ta klasa LambdaBinding nie jest wbudowana; musisz dołączyć plik LambdaBinding.cs.

Nota boczna. To wstyd, że XAML nie zezwala na wyrażenia. Tak, zdaję sobie sprawę, że XAML ma być "dla projektantów" i wolny od tej nieuchwytnej rzeczy, którą nazywamy logiką aplikacji , ale kogo tutaj żartujemy ... Po pierwsze, w drugiej odpowiedzi pokazany jest DataTrigger, który jest w zasadzie wyrażeniem warunkowym, i tak nie różni się (tylko dużo dłuższa) niż {Binding source.SelectedIndex >= 0}. Po drugie, jeśli pomysł jest prosty, to wiążące wyrażenia, które projektant powinien być w stanie napisać, wykraczają daleko poza możliwości nie programisty ... jeśli potrzebujesz dowodu, rozważ coś takiego:

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