Tengo un montón de casillas de verificación en mi formulario con sus propiedades marcadas vinculadas a propiedades booleanas en el modelo de datos:
chk1.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty1", false)) chk2.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty2", false)) chk3.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty3", false))También hay un controlador de eventos compartido para todas las casillas de verificación en la pantalla que garantiza que el valor del enlace de datos se establezca correctamente en el valor marcado.
private void AllCheckboxes_CheckedChanged(object sender, EventArgs e) { var chk = ((CheckBox)sender); var binding = chk.DataBindings["Checked"]; if (binding != null) binding.WriteValue(); }En algunos casos, la primera vez que se cargan este formulario y los enlaces, aparece una excepción:
No se puede formatear el valor al tipo deseado.
en System.ComponentModel.ReflectPropertyDescriptor.SetValue(componente de objeto, valor de objeto) en System.Windows.Forms.BindToObject.SetValue(valor de objeto) en System.Windows.Forms.Binding.PullData(reformato booleano, fuerza booleana) en System.Windows .Forms.Binding.WriteValue()
Funciona correctamente para que la primera casilla de verificación procese el evento, pero luego la segunda arrojará esta excepción.
La fuente de datos es una interfaz de mi modelo de datos.
public interface IMyDataModel { bool MyBooleanProperty1 { get; set; } bool MyBooleanProperty2 { get; set; } bool MyBooleanProperty3 { get; set; } }Y puedo verificar que el modelo de datos en sí esté configurado correctamente estableciendo un punto de interrupción justo antes de .WriteValue en el controlador de eventos. Incluso puedo poner un punto de interrupción en el setter de la propiedad booleana enlazada, y también se llama correctamente.
Si configuro la propiedad FormattingEnabled del enlace en verdadero, soluciona el problema. Pero me pregunto por qué tengo que hacer eso en primer lugar, ya que estoy vinculando una propiedad System.Boolean en el objeto UI a una propiedad bool en la fuente de datos.
¿Por qué obtendría esta excepción en este caso?
Es difícil decir con certeza qué está pasando sin una forma de reproducir el problema.
Pero al menos puedo explicar por qué configurar FormattingEnabled hace que la excepción desaparezca:
WriteData llama a PullData con reformat = true y force = true .
Desde su pila de llamadas, parece que debe estar ingresando en este bloque:
// Put the value into the data model if (!parseFailed) { this.bindToObject.SetValue(parsedValue); } Inmediatamente después de eso, la excepción se vuelve a generar a menos que FormattingEnabled = true . Por lo tanto, configurar FormattingEnabled aquí oculta el problema, ya que parece que Binding asume que usted mismo manejará cualquier problema de formato/análisis que haya encontrado hasta ahora.
En cuanto a por qué se lanza la excepción en primer lugar... No lo sé. Nada es obvio mirando aquí:
Tendría curiosidad por saber si su problema persiste si encuentra una manera de agregar sus enlaces de datos sin su clase personalizada BindingValue . También me gustaría saber si tiene algún oyente conectado en BindingValue .
Creo que arroja una excepción si no se maneja el análisis/formato, razón por la cual formattingEnabled parece funcionar.
Intente manejar los eventos Binding.Format y Binding.Parse para verificar que los tipos que envía (y espera) sean correctos.
Esto es lo que haría. El modelo debe implementar la interfaz INotifyPropertyChanged . Agregue un BindingSource a su formulario desde ToolBox. Establezca el DataSource de él en su modelo. En cada casilla de verificación, establezca el enlace de datos. Usaría la ventana Avanzado y establecería el Modo de actualización de fuente de datos en OnPropertyChanged . En este caso, no tiene que configurar ningún controlador de eventos para sus casillas de verificación.