Як я можу забезпечити декілька умов для запуску даних у WPF?
Як я можу забезпечити декілька умов для запуску даних у WPF?
Відповіді:
Використовуйте тип MultiDataTrigger
<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 - якщо ви хочете мати "або", тоді заперечуйте всі умови, оскільки (A і B) <=> ~ (~ A або ~ B)
але якщо у вас є інші значення, ніж булеві, спробуйте перетворити тип:
<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>
ви можете використовувати значення методу «Перетворити» будь-яким способом, щоб створити умову, яка вам підходить.
conditionConverter
? Як ми визначаємо or
в цьому прикладі "Портленд" і "АБО" як наші два варіанти?
Щоб розробити відповідь @ serine та проілюструвати роботу з нетривіальною багатозначною умовою: у мене виникла потреба показати накладення "затемнення" на елементі для булевого стану NOT a AND (b OR NOT c)
.
На задньому плані це питання "Вибір з вибором". Якщо користувач вибере неправильну відповідь, він стає відключеним (затемнено і не може бути обраний знову). Автоматизований агент має можливість зосередитись на будь-якому конкретному виборі, щоб дати пояснення (підкреслена межа). Коли агент фокусується на елементі, його не слід затемнювати, навіть якщо його вимкнено . Усі елементи, які не знаходяться в фокусі, позначені дефокусованими і повинні бути затемнені.
Логіка затемнення така:
NOT IsFocused AND (IsDefocused OR NOT Enabled)
Щоб реалізувати цю логіку, я зробив загальний IMultiValueConverter
назви (незграбно), щоб відповідати моїй логіці
// '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 я використовую це в MultiDataTrigger
в <Style><Style.Triggers>
ресурсі
<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>
А для повноти мій перетворювач визначений в a 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>
ЦІЙ ВІДПОВІДЬ
ТІЛЬКО АНІМАЦІЙ Якщо ви хочете реалізувати логіку AND, вам слід скористатись MultiTrigger, ось ось приклад:
Припустимо, ми хочемо виконати деякі дії, якщо властивість Text = "" (порожня рядок) AND IsKeyboardFocused = "False", то Ваш код повинен мати такий вигляд:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<!-- Your actions here -->
</MultiTrigger.EnterActions>
</MultiTrigger>
Якщо ви хочете реалізувати логіку АБО, є кілька способів, і це залежить від того, що ви намагаєтеся зробити:
Перший варіант - використовувати кілька тригерів.
Отже, припустимо, ви хочете щось зробити, якщо або Text = "" АБО IsKeyboardFocused = "Невірно",
ваш код повинен виглядати приблизно так:
<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>
Але проблема в тому, що я зроблю, якщо хочу зробити щось, якщо або текст НЕ нуль, або IsKeyboard = "Істинно"? Цього можна досягти другим підходом:
пригадайте правило Де Моргана, яке говорить! (! X &&! Y) = x || у.
Таким чином , ми будемо використовувати його для вирішення попередньої задачі, написавши мульти тригер, він спрацьовує , коли Text = "" і IsKeyboard = «True», і ми зробимо все наші дії в ВИЇЗНИХ ЗАХОДІВ , як це:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.ExitActions>
<!-- Do something here -->
</MultiTrigger.ExitActions>
</MultiTrigger>