2015-06-19 26 views
13

Mam kilka pól wyboru na mojej postaci z ich Sprawdzone właściwości związane z właściwościami logicznych na modelu danych:Dlaczego otrzymam wyjątek formatu podczas aktualizowania powiązania logicznego za pomocą funkcji 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)) 

Istnieje również wspólna obsługi zdarzeń dla wszystkich wyboru na ekranie, który zapewnia wartość z danymi jest poprawnie ustawione na sprawdzoną wartość.

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

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

W niektórych przypadkach, po raz pierwszy ta forma i powiązania są ładowane, otrzymuję wyjątek:

nie można sformatować wartość żądanego typu.

w System.ComponentModel.ReflectPropertyDescriptor.SetValue Component Object (obiekt), wartości w System.Windows.Forms.BindToObject.SetValue (wartość obiektu) w System.Windows.Forms.Binding.PullData (logiczna reformat, logiczna siła) w System.Windows.Forms.Binding.WriteValue()

on działa poprawnie pierwszego wyboru do przetwarzania zdarzeń, a następnie drugi usunie tego wyjątku.

Źródłem danych jest interfejsem mojego datamodel

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

I mogę zweryfikować, że sam model danych jest ustawiony prawidłowo przez ustawienie punktu przerwania tuż przed .WriteValue w obsługi zdarzeń. Mogę nawet umieścić punkt przerwania w ustawianiu związanej właściwości boolowskiej, i jest ona również nazywana poprawnie.

Jeśli ustawię właściwość FormattingEnabled wiązania na wartość true, problem zostanie rozwiązany. Ale zastanawiam się, dlaczego w ogóle muszę to zrobić, ponieważ wiążę właściwość System.Boolean w obiekcie interfejsu użytkownika z właściwością bool w źródle danych.

Dlaczego miałbym otrzymać ten wyjątek w tym przypadku?

+0

czy włączona 'własności IsThreeState'? –

+0

Nie, IsThreeState nie jest ustawiony – Rachel

+0

Chciałbym ustawić "IsThreeState" lub uczynić twoje powiązanie z zerowalnym boolem. Rozumiem, że nie wygląda to na problem wiążący o wartości zerowej, ale oczekuję, że w polach wyboru będzie mieć pustą obsługę. –

Odpowiedz

1

Trudno powiedzieć na pewno, co się dzieje, bez możliwości odtworzenia problemu.

Ale przynajmniej mogę wyjaśnić, dlaczego ustawienie FormattingEnabled czyni wyjątek odejść:

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

WriteData rozmowy PullData z reformat = true i force = true.

ze swojego stosu wywołań, to wygląda na to, że musi być co go do tego bloku:

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

Natychmiast po tym, wyjątek jest rethrown chybaFormattingEnabled = true. Ustawienie tutaj FormattingEnabled ukrywa problem, ponieważ wydaje się, że Binding zakłada, że ​​poradzisz sobie z problemami związanymi z formatowaniem/parsowaniem, które zostały znalezione do tej pory.

Co do tego, dlaczego wyjątek jest rzucany w pierwszej kolejności ... Nie wiem.Nic nie jest oczywiste, patrząc tutaj:

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

byłbym ciekaw, czy problem nadal występuje, jeśli znaleźć sposób, aby dodać swoje powiązania danych bez twojej klasy BindingValue niestandardowej. Byłbym też ciekawy, czy masz jakichś słuchaczy połączonych w BindingValue.

+1

Dziękuję za kod linki, te pomoc. Zawęziłem problem do czegoś spowodowanego przez nasz wewnętrzny kod powiadomienia o zmianie w get/zestawie nieruchomości. Używanie zwykłego generycznego 'get; set; 'nie powoduje wyjątku. Nagradzam cię nagrodą, ponieważ linki do kodu MSDN dostarczają najlepszego wyjaśnienia, dlaczego dostaję błąd i podpowiadam skąd może pochodzić, więc będę kontynuować debugowanie w tym kierunku później, kiedy będę mieć więcej czasu . Dziękuję Ci. – Rachel

0

Myślę, że zgłasza wyjątek, jeśli parse/format nie jest obsługiwany, dlatego wydaje się, że działa formattingEnabled.

Spróbuj przeprowadzić obsługę zdarzeń Binding.Format i Binding.Parse, aby sprawdzić, czy typy wysyłane (i oczekują) są poprawne.

+0

Oba te zdarzenia poprawnie pokazują 'e.DesiredType' i' e.Value', aby być 'System.Boolean'. Wygląda na to, że obydwa trafiają poprawnie bez żadnych wyjątków. – Rachel

0

Oto co bym zrobił. Model powinien implementować interfejs INotifyPropertyChanged. Dodaj BindingSource do formularza z ToolBox. Ustaw model DataSource tego modelu. Na każdym polu wyboru ustaw powiązanie danych. Chciałbym użyć okna Zaawansowane i ustawić tryb aktualizacji źródła danych na OnPropertyChanged. W takim przypadku nie trzeba ustawiać żadnej procedury obsługi zdarzeń dla swoich pól wyboru.

+0

W lepszym świecie użyłbym 'INotifyPropertyChanged', jednak nie mam kontroli nad infrastrukturą aplikacji w tym przypadku i nie mogę go zmienić bez wielu kłopotów. Ponadto szukam odpowiedzi na pytanie, dlaczego tak się dzieje, a nie na potencjalne poprawki. – Rachel

0

Spróbuj poprzez umożliwienie formatowania następujące znaczenie:

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

Można również przejść następującą link-

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

+1

Jak już powiedziałem w moim pytaniu, wiem, że włączenie formatowania "naprawi" to, ale chcę wiedzieć, co jest przyczyną problemu w pierwszej kolejności. – Rachel