2015-06-19 17 views
13

Ho un mucchio di caselle di controllo sulla mia forma con le loro proprietà Checked legati alle proprietà booleane sul modello di dati:Perché dovrei ottenere un'eccezione di formato durante l'aggiornamento di un'associazione booleana con WriteValue?

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)) 

C'è anche un gestore di eventi condiviso per tutte le caselle di controllo sullo schermo che garantisce il valore databound è correttamente impostato sul valore selezionato.

private void AllCheckboxes_CheckedChanged(object sender, EventArgs e) 
{ 
    var chk = ((CheckBox)sender); 

    var binding = chk.DataBindings["Checked"]; 
    if (binding != null) 
     binding.WriteValue(); 
} 

In alcuni casi, per la prima volta questo modulo e le associazioni sono caricati, ottengo un'eccezione:

Non è possibile formattare il valore al tipo desiderato.

a System.ComponentModel.ReflectPropertyDescriptor.SetValue (Component Object, Object value) al System.Windows.Forms.BindToObject.SetValue (Object value) a System.Windows.Forms.Binding.PullData (riformattazione booleano, booleano forza) a System.Windows.Forms.Binding.WriteValue()

funziona correttamente per la prima casella di controllo per elaborare l'evento, ma poi la seconda getterà questa eccezione.

La fonte dei dati è un'interfaccia del mio DataModel

public interface IMyDataModel 
{ 
    bool MyBooleanProperty1 { get; set; } 
    bool MyBooleanProperty2 { get; set; } 
    bool MyBooleanProperty3 { get; set; } 
} 

e posso verificare che il modello di dati in sé sia ​​impostata correttamente impostando un diritto punto di interruzione prima della .WriteValue nel gestore di eventi. Posso persino inserire un punto di interruzione nel settatore della proprietà booleana associata, e viene anche chiamato correttamente.

Se ho impostato la proprietà FormattingEnabled del legame vero, lo fa risolvere il problema. Ma mi chiedo perché debba farlo anche in primo luogo, poiché lego una proprietà System.Boolean nell'oggetto UI a una proprietà bool nell'origine dati.

Perché dovrei essere sempre questa eccezione in questo caso?

+0

hai abilitato 'immobili IsThreeState'? –

+0

No, IsThreeState non è impostato – Rachel

+0

Vorrei provare a impostare 'IsThreeState' o rendere l'associazione a nullable bool. Capisco che questo non sembri un problema di associazione nullo, ma mi aspetto di avere una gestione nulla nelle caselle di controllo. –

risposta

1

E 'difficile dire con certezza cosa sta succedendo senza un modo per riprodurre il problema.

Ma almeno posso spiegare il motivo per cui l'impostazione FormattingEnabled fa eccezione andare via:

http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Binding.cs,853

WriteData chiamate PullData con reformat = true e force = true.

Dal vostro stack di chiamate, sembra che si deve essere fare in questo blocco:

  // Put the value into the data model 
      if (!parseFailed) { 
       this.bindToObject.SetValue(parsedValue); 
      } 

Subito dopo che, l'eccezione viene rilanciati menoFormattingEnabled = true. Quindi, l'impostazione FormattingEnabled nasconde il problema, dal momento che sembra che Binding presupponga che tu gestirai qualsiasi problema di formattazione/analisi che è stato trovato finora.

Per quanto riguarda il motivo per cui viene generata l'eccezione, in primo luogo ... non lo so.Nulla è evidente guardando qui:

http://referencesource.microsoft.com/#system/compmod/system/componentmodel/ReflectPropertyDescriptor.cs,1138

Sarei curioso di sapere se il problema persiste se si trova un modo per aggiungere le associazioni di dati senza la classe BindingValue personalizzato. Sarei anche curioso di sapere se hai degli ascoltatori cablati su BindingValue.

+1

Grazie per il codice collegamenti, questi aiutano. Ho ristretto il problema a qualcosa causato dal nostro codice di notifica delle modifiche interne nel get/set della proprietà. Usando un generico normale get; set; 'non causa l'eccezione. Ti sto assegnando la taglia perché i link al codice MSDN forniscono la spiegazione migliore del motivo per cui sto ricevendo l'errore e ti suggerisco da dove provenire, quindi continuerò a eseguire il debug in quella direzione più avanti, quando avrò più tempo . Grazie. – Rachel

0

Penso che generi un'eccezione se parse/formato non viene gestito, motivo per cui formattingEnabled sembra funzionare.

Provare a gestire gli eventi Binding.Format e Binding.Parse per verificare che i tipi che invia (e si aspetta) siano corretti.

+0

Entrambi questi eventi mostrano correttamente 'e.DesiredType' e' e.Value' per essere un 'System.Boolean'. Inoltre sembrano entrambi colpiti correttamente, senza eccezioni. – Rachel

0

Questo è quello che vorrei fare. Il modello deve implementare l'interfaccia INotifyPropertyChanged. Aggiungi un BindingSource al modulo da ToolBox. Impostare lo DataSource nel modello. Su ogni casella di controllo, imposta l'associazione dati. Vorrei utilizzare la finestra Avanzate e impostare la modalità di aggiornamento dell'origine dati su OnPropertyChanged. In questo caso non è necessario impostare alcun gestore di eventi per le caselle di controllo.

+0

In un mondo migliore userei 'INotifyPropertyChanged', ma in questo caso non ho il controllo dell'infrastruttura dell'applicazione e non posso cambiarlo senza un sacco di problemi. Inoltre, sto cercando una risposta sul motivo per cui questo si sta verificando, non per potenziali correzioni. – Rachel

0

Prova abilitando la formattazione i seguenti-

this.chk1.DataBindings.Add(new System.Windows.Forms.Binding("EditValue", this.bindingSource1, "MyProperty", true)); 

Si può anche passare attraverso il seguente link-

http://msdn.microsoft.com/en-us/library/system.windows.forms.binding.formattingenabled.aspx

+1

Come ho già detto nella mia domanda, so che abilitare la formattazione lo "sistemerà", ma voglio sapere in primo luogo cosa sta causando il problema. – Rachel