Lo que tengo es un objeto que tiene una IsReadOnly
propiedad. Si esta propiedad es verdadera, me gustaría establecer la IsEnabled
propiedad en un Botón, (por ejemplo), en falso.
Me gustaría creer que puedo hacerlo tan fácilmente como IsEnabled="{Binding Path=!IsReadOnly}"
eso, pero eso no vuela con WPF.
¿Estoy relegado a tener que pasar por todas las configuraciones de estilo? Simplemente parece demasiado prolijo para algo tan simple como establecer un bool en el inverso de otro 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>
Respuestas:
Puede usar un ValueConverter que invierta una propiedad bool por usted.
XAML:
Convertidor:
fuente
!
, ese es un código de largo aliento ... La gente hace grandes esfuerzos para separar lo que sienten que es "código" de esos diseñadores pobres. Extra extra doloroso cuando soy tanto el codificador como el diseñador.¿Has considerado una
IsNotReadOnly
propiedad? Si el objeto que está vinculado es un ViewModel en un dominio MVVM, entonces la propiedad adicional tiene mucho sentido. Si se trata de un modelo de entidad directo, puede considerar la composición y presentar un ViewModel especializado de su entidad al formulario.fuente
Con el enlace estándar necesita usar convertidores que parezcan poco ventosos. Por lo tanto, le recomiendo que mire mi proyecto CalcBinding , que fue desarrollado especialmente para resolver este problema y algunos otros. Con el enlace avanzado puede escribir expresiones con muchas propiedades de origen directamente en xaml. Digamos que puedes escribir algo como:
o
o
o
donde A, B, C, IsChecked - propiedades de viewModel y funcionará correctamente
fuente
<Setter.Value><cb:Binding Path="!IsReadOnly" /></Setter.Value>
obtiene un 'Enlace' no es válido para Setter. Error de tiempo de compilación del valorYo recomendaría usar https://quickconverter.codeplex.com/
Invertir un booleano es tan simple como:
<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
Eso acelera el tiempo que normalmente se necesita para escribir convertidores.
fuente
Quería que mi XAML siguiera siendo lo más elegante posible, así que creé una clase para envolver el bool que reside en una de mis bibliotecas compartidas, los operadores implícitos permiten que la clase se use como un bool en código subyacente sin problemas
Los únicos cambios necesarios para su proyecto son hacer que la propiedad que desea invertir devuelva esto en lugar de bool
Y en el postfix XAML el enlace con Value o Invert
fuente
bool
Expresiones / Variables de tipo, incluso sin hacer referencia al valor inverso. En su lugar, agregaría un método de extensión "No" alBoolean
Struct
.Property
vs.Method
paraBinding
. Mi declaración de "desventaja" todavía se aplica. Por cierto, el método de extensión "No" booleano sigue siendo útil para evitar el "!" Operador que se pierde fácilmente cuando (como suele ser el caso) está incrustado junto a los caracteres que se parecen (es decir, uno / más "(" 'y "l" y "I").Este también funciona para bools anulables.
fuente
Agregue una propiedad más en su modelo de vista, que devolverá el valor inverso. Y unir eso al botón. Me gusta;
a la vista modelo:
en xaml:
fuente
No sé si esto es relevante para XAML, pero en mi aplicación simple de Windows creé el enlace manualmente y agregué un controlador de eventos de formato.
fuente
Format
y losParse
eventos en los enlaces WinForms son aproximadamente equivalentes al convertidor WPF.Tuve un problema de inversión, pero una solución ordenada.
La motivación era que el diseñador de XAML mostraría un control vacío, por ejemplo, cuando no había datacontext / no
MyValues
(itemssource).Código inicial: oculta el control cuando
MyValues
está vacío. Código mejorado: muestra el control cuandoMyValues
NO es nulo o está vacío.Por supuesto, el problema es cómo expresar '1 o más elementos', que es lo opuesto a 0 elementos.
Lo resolví agregando:
Ergo establece el valor predeterminado para el enlace. Por supuesto, esto no funciona para todo tipo de problemas inversos, pero me ayudó con un código limpio.
fuente
💡 .Net Core Solution 💡
Maneja situaciones nulas y no arroja una excepción, pero regresa
true
si no se presenta ningún valor; de lo contrario toma el booleano ingresado y lo invierte.Xaml
App.Xaml Me gusta poner todas mis estadísticas de convertidor en el archivo app.xaml para no tener que volver a declararlas en las ventanas / páginas / controles del proyecto.
Para que quede claro
converters:
es el espacio de nombres para la implementación real de la clase (xmlns:converters="clr-namespace:ProvingGround.Converters"
).fuente
Siguiendo la respuesta de @ Paul, escribí lo siguiente en ViewModel:
Espero que tener un fragmento aquí ayude a alguien, probablemente novato como soy.
Y si hay un error, ¡házmelo saber!
Por cierto, también estoy de acuerdo con el comentario de @heltonbiker: definitivamente es el enfoque correcto solo si no tiene que usarlo más de 3 veces ...
fuente
Hice algo muy similar Creé mi propiedad detrás de escena que permitía la selección de un cuadro combinado SOLO si había terminado de buscar datos. Cuando mi ventana aparece por primera vez, inicia un comando cargado asíncrono, pero no quiero que el usuario haga clic en el cuadro combinado mientras todavía está cargando datos (estaría vacío, luego se llenaría). Entonces, por defecto, la propiedad es falsa, así que devuelvo el inverso en el captador. Luego, cuando estoy buscando, configuro la propiedad en verdadero y de nuevo en falso cuando se completa.
Luego, para el cuadro combinado, puedo vincularlo directamente a IsSearching:
fuente
Yo uso un enfoque similar como @Ofaim
fuente