O que tenho é um objeto que possui uma IsReadOnly
propriedade. Se essa propriedade for verdadeira, eu gostaria de definir a IsEnabled
propriedade em um Button (por exemplo) como false.
Eu gostaria de acreditar que posso fazê-lo tão facilmente quanto IsEnabled="{Binding Path=!IsReadOnly}"
isso, mas isso não ocorre com o WPF.
Estou relegado a ter que passar por todas as configurações de estilo? Apenas parece muito prolixo para algo tão simples quanto definir um bool para o inverso de outro bool.
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
Respostas:
Você pode usar um ValueConverter que inverte uma propriedade bool para você.
XAML:
Conversor:
fonte
!
isso, esse é um código demorado ... As pessoas enviam esforços insanos para separar o que consideram "código" daqueles pobres designers. Extra extra doloroso quando eu sou o codificador e o designer.Você já considerou uma
IsNotReadOnly
propriedade? Se o objeto que está sendo vinculado for um ViewModel em um domínio MVVM, a propriedade adicional fará todo sentido. Se for um modelo direto de entidade, considere a composição e a apresentação de um ViewModel especializado da sua entidade no formulário.fonte
Com a ligação padrão, você precisa usar conversores com um pouco de vento. Portanto, recomendo que você analise meu projeto CalcBinding , desenvolvido especialmente para resolver esse problema e outros. Com a ligação avançada, você pode escrever expressões com muitas propriedades de origem diretamente no xaml. Digamos, você pode escrever algo como:
ou
ou
ou
onde A, B, C, IsChecked - propriedades do viewModel e ele funcionará corretamente
fonte
<Setter.Value><cb:Binding Path="!IsReadOnly" /></Setter.Value>
recebe uma 'ligação' não é válido para o erro tempo de compilação Setter.Value'Eu recomendaria usar https://quickconverter.codeplex.com/
A inversão de um booleano é tão simples quanto:
<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
Isso acelera o tempo normalmente necessário para gravar conversores.
fonte
Eu queria que meu XAML permanecesse o mais elegante possível, então criei uma classe para agrupar o bool que reside em uma das minhas bibliotecas compartilhadas, os operadores implícitos permitem que a classe seja usada como um bool no code-behind sem problemas
As únicas alterações necessárias ao seu projeto são fazer com que a propriedade que você deseja inverter retorne isso em vez de bool
E no XAML postfix a ligação com Value ou Invert
fonte
bool
expressões / variáveis de tipo, mesmo sem fazer referência ao valor inverso. Em vez disso, eu adicionaria um método de extensão "Não" ao arquivoBoolean
Struct
.Property
vs.Method
paraBinding
. Minha declaração "Downside" ainda se aplica. Aliás, o método de extensão "Not" 'booleano' ainda é útil para evitar o "!" Operador que é facilmente esquecido quando (como costuma ser o caso) é incorporado ao lado de caracteres que se parecem com ele (ou seja, um / mais "(" 's e "l" e "I")Este também funciona para bools anuláveis.
fonte
Adicione mais uma propriedade no seu modelo de exibição, que retornará valor reverso. E ligue isso ao botão. Gostar;
no modelo de exibição:
no xaml:
fonte
Não sei se isso é relevante para o XAML, mas no meu aplicativo Windows simples, criei a ligação manualmente e adicionei um manipulador de eventos Format.
fonte
Format
eParse
eventos nas ligações WinForms são aproximadamente equivalentes ao conversor WPF.Eu tive um problema de inversão, mas uma solução pura.
A motivação foi que o designer XAML mostraria um controle vazio, por exemplo, quando não havia datacontext / no
MyValues
(itemssource).Código inicial: oculta o controle quando
MyValues
está vazio. Código aprimorado: mostre o controle quandoMyValues
NÃO for nulo ou vazio.Obviamente, o problema é como expressar '1 ou mais itens', que é o oposto de 0 itens.
Eu o resolvi adicionando:
Ergo definindo o padrão para a encadernação. Claro que isso não funciona para todos os tipos de problemas inversos, mas me ajudou com um código limpo.
fonte
Solution .Net Core Solution 💡
Lida com a situação nula e não lança uma exceção, mas retorna
true
se nenhum valor for apresentado; caso contrário, pega o booleano inserido e o inverte.Xaml
App.Xaml Gosto de colocar todas as estatísticas do meu conversor no arquivo app.xaml para não precisar redeclará-las nas janelas / páginas / controles do projeto.
Para ser claro,
converters:
é o espaço para nome da implementação real da classe (xmlns:converters="clr-namespace:ProvingGround.Converters"
).fonte
Após a resposta de @ Paul, escrevi o seguinte no ViewModel:
Espero que ter um trecho aqui ajude alguém, provavelmente novato como eu.
E se houver algum erro, avise-me!
BTW, eu também concordo com o comentário @heltonbiker - é definitivamente a abordagem correta apenas se você não precisar usá-la mais de três vezes ...
fonte
Eu fiz algo muito parecido. Criei minha propriedade nos bastidores que permitia a seleção de uma caixa de combinação SOMENTE se ela terminasse de pesquisar dados. Quando minha janela aparece pela primeira vez, ele lança um comando carregado assíncrono, mas não quero que o usuário clique na caixa de combinação enquanto ainda carrega dados (estaria vazio e preenchido). Então, por padrão, a propriedade é false, então eu retorno o inverso no getter. Então, quando estou pesquisando, defino a propriedade como true e retorne para false quando concluir.
Em seguida, para a caixa de combinação, posso vinculá-lo diretamente ao IsSearching:
fonte
Eu uso uma abordagem semelhante como @Ofaim
fonte