2010-07-29 11 views

Respuesta

60
<RadioButton GroupName="Group1" 
      IsChecked="{Binding PropertyValue}" Content="Yes" /> 
<RadioButton GroupName="Group1" Content="No" 
      IsChecked="{Binding PropertyValue, 
         Converter={StaticResource BoolInverterConverter}}" /> 
public class BoolInverterConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     if (value is bool) 
     { 
      return !(bool)value; 
     } 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     if (value is bool) 
     { 
      return !(bool)value; 
     } 
     return value; 
    } 

    #endregion 
} 
+0

muchas gracias! – no9

+23

Por alguna razón debo usar dos GroupNames diferentes. De lo contrario, el booleano en el modelo de vista se puede establecer en verdadero, pero nunca se restablece en falso (aunque los botones de radio parecen comportarse correctamente) – Qwertie

+0

Hola, se te olvidó "/" para cerrar el segundo botón de opción. –

9

Se puede utilizar un valor-convertidor que revierte el valor booleano:

Con ese convertidor, enlazar una Checkbox.IsChecked-propiedad en el valor booleano sin el convertidor y una CheckBox.IsChecked-propiedad con el convertidor. Esto debería funcionar.

Aquí el código para un convertidor de este tipo. Lo he copiado desde here y he agregado algunas líneas de código. Allí encontrarás más información sobre.

public class BoolToOppositeBoolConverter : IValueConverter { 
    public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) { 
     if (targetType != typeof(bool)) { 
      throw new InvalidOperationException("The target must be a boolean"); 
     } 
     if (null == value) { 
      return null; 
     } 
        return !(bool)value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) { 
     if (targetType != typeof(bool)) { 
      throw new InvalidOperationException("The target must be a boolean"); 
     } 
     if (null == value) { 
      return null; 
     } 
     return !(bool)value; 
    } 
} 

Para usarlo, declararlo en la sección de recursos.

<local:BoolToOppositeBoolConverter x:Key="BoolToOppositeBoolConverter_ValueConverter"/> 

Y el uso en la unión como un recurso estático:

<CheckBox IsChecked="{Binding YourProperty}" /> 
<CheckBox IsChecked="{Binding YourProperty,Converter={StaticResource BoolToOppositeBoolConverter_ValueConverter}}" /> 

Tenga en cuenta, el convertidor no es más que un ejemplo sencillo. Impleméntelo ordenadamente si desea usarlo en el código productivo. No lo he probado. Haz un comentario si no está funcionando.

+1

thanx! He utilizado la solución Ragunathan, pero ambos funcionan muy bien. Speacialy me gustaría agradecerle por su explicación y tiempo invertido. Poco a poco estoy cavando en WPF ... – no9

2

se puede lograr esto sin un convertidor si se establece la propiedad GroupName de dos botones de radio con el mismo valor (por lo que sólo se puede controlar en el momento). Luego, establezca IsChecked de un botón de radio en "Verdadero" y enlace IsChecked de otro en su Boolean. Al cambiar los botones de opción, se cambiará el valor booleano; sin embargo, al cambiar el valor booleano a False, no se verificará el otro botón de opción.

Gracias, Vlad

+1

Este enfoque tiene un efecto secundario de enlace intermitente si muestra el cuadro de diálogo varias veces. Pude solucionarlo limpiando la propiedad Contexto de datos antes de cerrar el cuadro de diálogo, por lo que me parece un problema de marco. De todos modos, se me ocurrió una solución mejor que admite Boolean y enumeraciones, y funciona correctamente si la propiedad GroupName está configurada o no. – votrubac

3

El enfoque de enlace estándar tiene el desafortunado efecto secundario de disparar el enlazador de enlaces como "no seleccionado" cada vez que se carga la IU. Entonces, si tienes código para manejar los clics del usuario en el setter para tu bool, hará algunas cosas raras como disparar al colocador a "falso", aunque lo hayas enlazado a un bool "verdadero".

llegué alrededor de este con un convertidor utilizado específicamente para los botones de radio:

public class BoolRadioConverter : IValueConverter 
{ 
    public bool Inverse { get; set; } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     bool boolValue = (bool) value; 

     return this.Inverse ? !boolValue : boolValue; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     bool boolValue = (bool)value; 

     if (!boolValue) 
     { 
      // We only care when the user clicks a radio button to select it. 
      return null; 
     } 

     return !this.Inverse; 
    } 
} 

En sus recursos:

<converters:BoolRadioConverter x:Key="BoolRadioConverter" /> 
<converters:BoolRadioConverter x:Key="InverseBoolRadioConverter" Inverse="True" /> 

En su xaml:

<RadioButton 
    Content="True option" 
    GroupName="radioGroup1" 
    IsChecked="{Binding MyProperty, 
         Converter={StaticResource BoolRadioConverter}}" /> 
<RadioButton 
    Content="False option" 
    GroupName="radioGroup2" 
    IsChecked="{Binding MyProperty, 
         Converter={StaticResource InverseBoolRadioConverter}}" /> 
+0

¡Genial! funciona como se esperaba para mi problema Copié para poner en mi blog para referencia futura – EvilInside

+0

y si lo llamo 'InverseBoolRadioConverter' podría ignorar la variable Inversa, y devolver verdadero porque siempre lo usaré como convertidor solo para botones de radio. – Maxoizs

0

versión simplificada de ragunathan 's answer.

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) => 
    Convert(value); 

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) => 
    Convert(value); 

private object Convert(object value) => 
    value is bool ? !(bool)value : value; 
Cuestiones relacionadas