2010-03-17 12 views
13

Bastante sencillo: estoy buscando hacer lo mismo que this pero en winforms. Todo lo que Google parece tirar hacia arriba es específica de WPF (. Es decir, no quiero hacer referencia a PresentationFramework.dll)vinculando un usercontrol al opuesto de una propiedad bool

explicarse si no desea leer el enlace:

La siguiente es una representación de la intención de lo que me gustaría hacer, aunque obviamente no funciona.

CheckBox1.DataBindings.Add(new Binding("Checked", this.object, "!SomeBool")); 

Respuesta

16

tiene dos opciones:

  1. crear el objeto Binding manualmente y se unen a los Format y Parse eventos y cambie el valor de cada uno.
  2. Crear una propiedad adicional de la clase que sólo se invierte la lógica de la propiedad destinada

La primera opción es más limpio, la OMI, ya que no obliga a la API de la clase a seguir el diseño de su interfaz de usuario, aunque el la segunda opción es (marginalmente) más fácil.

Ejemplo de Opción 1

private void SwitchBool(object sender, ConvertEventArgs e) 
{ 
    e.Value = !((bool)e.Value); 
} 

... 

Binding bind = new Binding("Checked", this.object, "SomeBool"); 

bind.Format += SwitchBool; 
bind.Parse += SwitchBool; 

CheckBox1.DataBindings.Add(bind); 

Ejemplo de Opción 2

public class SomeClass 
{ 
    public bool SomeBool { get; set; } 

    public bool NotSomeBool 
    { 
     get { return !SomeBool; } 
     set { SomeBool = !value; } 
    } 
} 

... 

CheckBox1.DataBindings.Add("Checked", this.object, "NotSomeBool"); 

Una vez más, estoy muy de opción a favor 1, ya que la opción 2 requiere que adaptar su clase a su Diseño de interfaz de usuario.

+0

+1 Me gusta su primera opción, no lo sabía :-) – Javier

+0

Conocía la opción 2, y probablemente debería haber mencionado que no quería poner la lógica de UI en mi modelo de dominio, por lo que no fue con eso Dicho esto, implementé la primera opción con éxito. Muchas gracias. Quiero señalar a cualquiera que pueda ver esto en el futuro: no puede agregar ese enlace a múltiples controles, uno debe crearse por control de UI (que es lo que quería hacer). –

+1

+1 para la primera opción, estaba tratando de resolver lo mismo. Implementé una extensión y una clase específica 'BooleanBinding' donde puedes definir si deseas unir lo opuesto o no según tu solución. Bloggeé sobre esto aquí: http://codewithpassion.blogspot.com/2010/11/binding-to-opposite-value-of-boolean.html –

1

Para ello, Me hacen una propiedad de sólo lectura llamado NotSomeBool, en la misma clase en la que tiene la propiedad SomeBool, y se unen a esta propiedad en su lugar.

+0

que confunde el objeto de dominio, la adición de un comportamiento específico de interfaz de usuario a la misma. –

+0

Bien, por eso prefiero la respuesta de Adam :-) ¡gracias! – Javier

+0

+1 aún así. Es una solución al problema, simplemente no es lo que estaba buscando. Gracias. –

6

Sobre la base de la respuesta de Adam me escribió una pequeña clase de ayuda:

class NegateBinding 
{ 
    string propertyName; 
    object dataSource; 
    string dataMember; 
    public NegateBinding(string propertyName, object dataSource, string dataMember) 
    { 
     this.propertyName = propertyName; 
     this.dataSource = dataSource; 
     this.dataMember = dataMember; 
    } 

    public static implicit operator Binding(NegateBinding eb) 
    { 
     var binding = new Binding(eb.propertyName, eb.dataSource, eb.dataMember, false, DataSourceUpdateMode.OnPropertyChanged); 
     binding.Parse += new ConvertEventHandler(negate); 
     binding.Format += new ConvertEventHandler(negate); 
     return binding; 
    } 

    static void negate(object sender, ConvertEventArgs e) 
    { 
     e.Value = !((bool)e.Value); 
    } 
} 

ya se puede utilizar de esta manera:

label1.DataBindings.Add(new NegateBinding("Visible", otherObject, "HasData")); 
+0

Buena introducción al 'operador implícito' y su uso ingenioso. – avenmore

Cuestiones relacionadas