Como posso fornecer várias condições para acionamento de dados no WPF?
Como posso fornecer várias condições para acionamento de dados no WPF?
Respostas:
Use o tipo 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 - se você deseja ter "ou", negue todas as condições, pois (A e B) <=> ~ (~ A ou ~ B)
mas se você tiver valores diferentes de booleano, tente usar conversores de tipo:
<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>
você pode usar os valores no método Convert da maneira que desejar para produzir uma condição que combina com você.
conditionConverter
faz? Como estamos especificando "Portland" e "OR" como nossas duas or
opções neste exemplo?
Para elaborar a resposta de @ serine e ilustrar o trabalho com uma condição com valores múltiplos não triviais: Eu precisava mostrar uma sobreposição de "escurecimento" em um item para a condição booleana NOT a AND (b OR NOT c)
.
Como pano de fundo, essa é uma pergunta de "múltipla escolha". Se o usuário escolher uma resposta errada, ela será desativada (esmaecida e não poderá ser selecionada novamente). Um agente automatizado tem a capacidade de se concentrar em qualquer opção específica para fornecer uma explicação (borda destacada). Quando o agente se concentra em um item, ele não deve ser esmaecido, mesmo se estiver desativado . Todos os itens que não estão focados são marcados como não focados e devem estar esmaecidos.
A lógica para escurecer é assim:
NOT IsFocused AND (IsDefocused OR NOT Enabled)
Para implementar essa lógica, criei um genérico IMultiValueConverter
chamado (sem jeito) para corresponder à minha lógica
// '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);
}
...
}
No XAML eu uso isso MultiDataTrigger
em um <Style><Style.Triggers>
recurso
<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>
E, para completar, meu conversor é definido em um 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>
ESTA RESPOSTA É APENAS PARA ANIMAÇÕES
Se você deseja implementar a lógica AND, deve usar o MultiTrigger, aqui está um exemplo:
Suponha que desejemos executar algumas ações se a propriedade Text = "" (string vazia) AND IsKeyboardFocused = "False", então seu código deve ter a seguinte aparência:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<!-- Your actions here -->
</MultiTrigger.EnterActions>
</MultiTrigger>
Se você deseja implementar a lógica OR, existem duas maneiras, e isso depende do que você tenta fazer:
A primeira opção é usar vários gatilhos.
Então, suponha que você queira fazer algo se Text = "" OR IsKeyboardFocused = "False",
seu código deve ser algo como isto:
<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>
Mas o problema é o que farei se eu quiser fazer algo se o texto NÃO for nulo OU IsKeyboard = "True"? Isso pode ser alcançado pela segunda abordagem:
lembre - se da regra de De Morgan, que diz! (! X &&! Y) = x || y
Então, vamos usá-lo para resolver o problema anterior, escrevendo um disparador múltiplo que é disparado quando Text = "" e IsKeyboard = "True", e faremos nossas ações em EXIT ACTIONS , assim:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.ExitActions>
<!-- Do something here -->
</MultiTrigger.ExitActions>
</MultiTrigger>