WPF'de veri tetikleyici için birden çok koşulu nasıl sağlayabilirim?
WPF'de veri tetikleyici için birden çok koşulu nasıl sağlayabilirim?
Yanıtlar:
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>
@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.
conditionConverter
? or
Bu örnekteki iki seçeneğimiz olarak "Portland" ve "VEYA" yı nasıl belirtiyoruz ?
@ 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, IMultiValueConverter
mantığı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 MultiDataTrigger
bir <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>
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>