Как я могу предоставить несколько условий для триггера данных в WPF?
Как я могу предоставить несколько условий для запуска данных в WPF?
Ответ 1
Используйте 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>
Ответ 2
@jasonk - если вы хотите иметь "или", то отрицаете все условия, поскольку (A и B) <= > ~ (~ A или ~ B)
но если у вас есть значения, отличные от boolean, попробуйте использовать преобразователи типов:
<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 любым способом, который вам нравится, чтобы создать условие, которое вам подходит.
Ответ 3
Чтобы подробно описать @serine answer и проиллюстрировать работу с нетривиальным многозначным условием: мне нужно было показать наложение "вычеркивания" на item для булевого условия 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>
И для полноты моей конвертер определен в 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>