Подтвердить что ты не робот

Почему я должен получить исключение формата при обновлении логического привязки с помощью 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))

Существует также общий обработчик событий для всех флажков на экране, который гарантирует, что значение базы данных правильно установлено на проверенное значение.

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

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

В некоторых случаях при первом загрузке этой формы и привязок я получаю исключение:

Невозможно отформатировать значение до требуемого типа.

в System.ComponentModel.ReflectPropertyDescriptor.SetValue(компонент объекта, значение объекта) в System.Windows.Forms.BindToObject.SetValue(значение объекта) в System.Windows.Forms.Binding.PullData(Boolean reformat, Boolean force) в System.Windows.Forms.Binding.WriteValue()

Он корректно работает для первого флажка, чтобы обработать событие, но затем второй будет генерировать это исключение.

Источник данных - это интерфейс моего datamodel

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

И я могу убедиться, что сама модель данных установлена ​​правильно, установив точку останова прямо перед .WriteValue в обработчике событий. Я даже могу поставить точку останова в сеттер связанного логического свойства, и он также называется правильно.

Если я установил свойство FormattingEnabled привязки к true, это устранит проблему. Но мне интересно, почему мне даже нужно это делать в первую очередь, поскольку я привязываю свойство System.Boolean в объекте пользовательского интерфейса к свойству bool в источнике данных.

Почему я должен получать это исключение в этом случае?

4b9b3361

Ответ 1

Трудно сказать наверняка, что происходит без способа воспроизвести проблему.

Но по крайней мере я могу объяснить, почему установка FormattingEnabled исключает исключение:

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

WriteData вызывает PullData с помощью reformat = true и force = true.

Из стека вызовов, похоже, вы должны сделать это в этом блоке:

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

Сразу же после этого исключение возвращается, если FormattingEnabled = true. Поэтому настройка FormattingEnabled здесь скрывает проблему, так как кажется, что Binding предполагает, что вы будете обрабатывать любые проблемы форматирования/разбора, которые она обнаружила до сих пор.

Что касается того, почему исключение выбрасывается в первую очередь... Я не знаю. Здесь нет ничего очевидного:

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

Мне было бы интересно узнать, сохраняется ли ваша проблема, если вы найдете способ добавить привязки данных без вашего BindingValue настраиваемого класса. Мне также было бы любопытно, есть ли у вас прослушиватели в BindingValue.

Ответ 2

Я думаю, что он генерирует исключение, если обрабатывать или анализировать не обрабатывается, поэтому formattingEnabled работает.

Попробуйте обработать события Binding.Format и Binding.Parse, чтобы проверить правильность типов, которые он отправляет (и ожидает).

Ответ 3

Это то, что я сделал бы. Модель должна реализовать интерфейс INotifyPropertyChanged. Добавьте BindingSource в форму с помощью ToolBox. Установите для него DataSource для вашей модели. На каждом флажке устанавливается привязка данных. Я бы использовал окно "Дополнительно" и установил режим обновления источника данных на OnPropertyChanged. В этом случае вам не нужно устанавливать какой-либо обработчик событий для ваших флажков.