WPF'de veri tetikleyici için birden çok koşulu nasıl sağlayabilirim?


Yanıtlar:


280

MultiDataTrigger türünü kullan

<Style TargetType="ListBoxItem">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Path=State}" Value="WA">
        <Setter Property="Foreground" Value="Red" />
      </DataTrigger>    
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding Path=Name}" Value="Portland" />
          <Condition Binding="{Binding Path=State}" Value="OR" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Background" Value="Cyan" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>

28
MultiTrigger'da "VEYA" ifadesi yapmanın bir yolu var mı? örneğin, ad = "portland" VEYA devlet = "VEYA"
jasonk

12
@jasonk - Bunu bir MultiTrigger ile yapıp yapamayacağınızdan emin değilsiniz. Bunun için iki tetikleyici tanımlayabilirsiniz ..
Gishu

2
Basit bir VEYA koşulu ifadesi ise, mantığı bir AND'e dönüşecek şekilde tersine çevirebilirsiniz. | koşul1 | koşul2 | sonuç | | true | true | gerçek | | true | false | gerçek | | false | true | gerçek | | false | false | yanlış | / VEYA doğru olup olmadığını denetlemek yerine, / VE öğesinin yanlış olduğunu denetleyin ve varsayılanı true olarak ayarlayın.
WeSam Abdallah

3
@WeSamAbdallah Koşulların yanlış olup olmadığını kontrol edemezsiniz.
Jim Balter

4
Basit bir dönüştürücü ile bir durumun yanlış olup olmadığını kontrol edebilirsiniz.
Paul

50

@jasonk - "veya" istiyorsanız, (A ve B) 'den bu yana tüm koşulları reddedin <=> ~ (~ A veya ~ B)

ancak boolean dışında değerleriniz varsa, türü dönüştürücüler kullanmayı deneyin:

<MultiDataTrigger.Conditions>
    <Condition Value="True">
        <Condition.Binding>
            <MultiBinding Converter="{StaticResource conditionConverter}">
                <Binding Path="Name" />
                <Binding Path="State" />
            </MultiBinding>
        </Condition.Binding>
        <Setter Property="Background" Value="Cyan" />
    </Condition>
</MultiDataTrigger.Conditions>

Convert yöntemindeki değerleri, size uygun bir koşul oluşturmak için istediğiniz şekilde kullanabilirsiniz.


3
Ah, her şeyi reddetmek ve bir VEYA durumuna çevirmek için akıllı hareket :)
myermian

8
Bu cevabı biraz daha genişletebilir misiniz? Nasıl kullanılacağından emin değilim. Ne yapar conditionConverter? orBu örnekteki iki seçeneğimiz olarak "Portland" ve "VEYA" yı nasıl belirtiyoruz ?
DLeh

4
@ cod3monk3y, bağlantınız koptu.
Spidermain50

22

@ Serine'nin cevabını detaylandırmak ve önemsiz olmayan çok değerli koşullarla çalışmayı göstermek için: Boolean koşulu için bir öğe üzerinde "dim-out" yer paylaşımını göstermem gerekiyordu NOT a AND (b OR NOT c).

Arka plan için bu bir "Çoktan Seçmeli" sorudur. Kullanıcı yanlış bir cevap alırsa devre dışı kalır (karartılır ve tekrar seçilemez). Otomatik bir aracı, bir açıklama (sınır vurgulanmış) vermek için herhangi bir seçime odaklanma yeteneğine sahiptir . Ajan bir öğeye odaklandığında , devre dışı bırakılsa bile karartılmamalıdır . Odaklı olmayan tüm öğeler işaretlenmiştir odaklı de , ve dışarı soluk edilmelidir.

Karartma mantığı bu nedenle:

NOT IsFocused AND (IsDefocused OR NOT Enabled)

Bu mantığı uygulamak için, IMultiValueConvertermantığımla eşleşmek üzere (garip bir şekilde) genel bir isim yaptım

// 'P' represents a parenthesis
//     !  a &&  ( b ||  !  c )
class NOT_a_AND_P_b_OR_NOT_c_P : IMultiValueConverter
{
    // redacted [...] for brevity
    public object Convert(object[] values, ...)
    {
        bool a = System.Convert.ToBoolean(values[0]);
        bool b = System.Convert.ToBoolean(values[1]);
        bool c = System.Convert.ToBoolean(values[2]);

        return !a && (b || !c);
    }
    ...
}

XAML'de bunu MultiDataTriggerbir <Style><Style.Triggers>kaynakta kullanıyorum

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <!-- when the equation is TRUE ... -->
        <Condition Value="True">
            <Condition.Binding>
                <MultiBinding Converter="{StaticResource NOT_a_AND_P_b_OR_NOT_c_P}">
                    <!-- NOT IsFocus AND ( IsDefocused OR NOT Enabled ) -->
                    <Binding Path="IsFocus"/>
                    <Binding Path="IsDefocused" />
                    <Binding Path="Enabled" />
                </MultiBinding>
            </Condition.Binding>
        </Condition>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.Setters>
        <!-- ... show the 'dim-out' overlay -->
        <Setter Property="Visibility" Value="Visible" />
    </MultiDataTrigger.Setters>
</MultiDataTrigger>

Ve tamlık uğruna, çeviricim bir ResourceDictionary

<ResourceDictionary xmlns:conv="clr-namespace:My.Converters" ...>
    <conv:NOT_a_AND_P_b_OR_NOT_c_P x:Key="NOT_a_AND_P_b_OR_NOT_c_P" />
</ResourceDictionary>

11
Bunun, bu şekilde kullanılacak dönüştürücülerin amacı olduğunu düşünmüyorum. Bunlar gerçekten görüntüleme için değerleri dönüştürmek içindir. Bu karmaşık hale geldiğinde, görünüm modelinde ihtiyacınız olanı veren hesaplanmış bir özellik oluşturun.
Martin Capodici

13
Yine de bu adlandırma
Kelly Elton

13
Programlamanın bir zanaat ve kodun zarif olduğunu hatırlamak için lütfen biraz sessizlik ayırın.
Bulanık Mantık

0

BU YANIT SADECE ANİMASYONLAR İÇİN


VE mantığını uygulamak istiyorsanız, MultiTrigger kullanmanız gerekir, işte bir örnek:

Text = "" (boş dize) AND IsKeyboardFocused = "False" özelliği varsa bazı eylemler yapmak istediğimizi varsayalım. kodunuz aşağıdaki gibi görünmelidir:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <!-- Your actions here -->
        </MultiTrigger.EnterActions>
</MultiTrigger>

OR mantığını uygulamak istiyorsanız, birkaç yol vardır ve ne yapmaya çalıştığınıza bağlıdır:

İlk seçenek birden fazla Tetikleyici kullanmaktır.
Bu nedenle, Text = "" VEYA IsKeyboardFocused = "False" olursa bir şey yapmak istediğinizi varsayalım
, kodunuz şöyle görünmelidir:

<Trigger Property="IsEnabled" Value="false">
    <Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
    <Setter Property="BorderBrush" TargetName="border" 
            Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>


Ama bu sorun ya Metin ISN'T null OR IsKeyboard = "True" bir şey yapmak istiyorum ne yapacağımdır ? Bu, ikinci yaklaşımla başarılabilir:
De Morgan'ın kuralını hatırlayın, diyor ki! (! X &&! Y) = x || y.
Tetiklendiğinde o Metin = "" ve IsKeyboard = "" Doğru, biz de eylemlerimizi yapacağız biz çok tetiği yazarak, önceki sorunu çözmek için kullanacağız Yani ÇIKIŞ EYLEMLER bu gibi:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.ExitActions>
        <!-- Do something here -->
    </MultiTrigger.ExitActions>
</MultiTrigger>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.