Привязка данных радиокнопки Windows Forms

Я следую шаблону проектирования модели представления, предложенному Martin Fowler для моей архитектуры графического интерфейса в проекте Windows Forms.

"Сущность модели презентации заключается в полностью автономном классе, который представляет все данные и поведение окна пользовательского интерфейса, но без каких-либо элементов управления, используемых для отображения этого пользовательского интерфейса на экране. Затем представление просто проецируется состояние презентации модели на стекле .... » - Мартин Фаулер

Я считаю эту концепцию очень гибкой и простой для понимания, за исключением одной проблемы, связанной с привязкой данных RadioButtons к свойствам объекта Data / Domain.

Предположим, у меня есть форма Windows с тремя переключателями для отображения некоторых параметров «Режим» как -

  • Авто
  • Руководство
  • Импортировать

Как я могу использовать логические свойства объектов данных / домена для привязки данных к этим кнопкам? Я пробовал много способов, но безуспешно. Например, я хотел бы написать такой код -

rbtnAutoMode.DataBindings.Add("Text", myBusinessObject, "IsAutoMode");
rbtnManualMode.DataBindings.Add("Text", myBusinessObject, "IsManualMode");
rbtnImportMode.DataBindings.Add("Text", myBusinessObject, "IsImportMode");

В объекте данных / домена должно быть четвертое свойство, такое как «SelectedMode», которое в конце должно отображать одно значение, например «SelectedMode = Auto». Я пытаюсь обновить это свойство при изменении любого из «IsAutoMode», «IsManualMode» или «IsImportMode», например через установщики свойств. У меня есть INotifyPropertyChanged, реализованный в моем объекте данных / домена, поэтому обновление любого свойства объекта данных / домена автоматически обновляет мои элементы управления пользовательского интерфейса, это не проблема.

Хороший пример привязки двух переключателей в вопросе о переполнении стека Как использовать привязку данных с переключателями Windows Forms?, но мне не хватает ссылки при реализации того же с тремя кнопками. У меня очень неустойчивое поведение переключателей.

Надеюсь, я смог разумно это объяснить. На самом деле я очень тороплюсь и не могу опубликовать подробный код, но приветствую любую помощь в этом отношении.

Есть простое решение этой проблемы, открыв такой метод, как -

public void SetMode(Modes mode)
{
  this._selectedMode = mode;
}

который мог бы быть вызван из события «CheckedChanged» переключателей из пользовательского интерфейса и идеально установил бы «SelectedMode» для бизнес-объекта, но мне нужно расширить пределы, чтобы проверить, можно ли это сделать с помощью DataBinding.


person Rajarshi    schedule 15.02.2010    source источник


Ответы (1)


Мой класс домена / бизнес-модели содержит свойство «Режим», имеющее тип «строка». Для режимов AUTO / MANUAL / IMPORT свойство Mode должно содержать соответственно «A» / «M» / «I». Моя модель предметной области получена моим классом модели презентации через конструктор в модели презентации.

Класс My Presentation Model содержит три логические переменные: IsAutoMode, IsManualMode, IsImportMode. Эти логические переменные будут использоваться для привязки данных к переключателям на форме. GET / SET для этих логических свойств немного расширен для обработки обновления соответствующего свойства («Mode») в модели предметной области. Обратите внимание на код свойства GET / SET в классе модели презентации ниже -

    public bool IsAutoMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "A";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "A" : _domainModel.Mode;
        }
    }
    public bool IsManualMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "M";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "M" : _domainModel.Mode;
        }
    }
    public bool IsImportMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "I";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "I" : _domainModel.Mode;
        }
    }

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

rbtnAutoMode.DataBindings.Add("Checked", _pmodel, "IsAutoMode");
rbtnManualMode.DataBindings.Add("Checked", _pmodel, "IsManualMode");
rbtnImportMode.DataBindings.Add("Checked", _pmodel, "IsImportMode");

и увидите, как летают привязки данных вашей радиокнопки. Текущий пример действителен независимо от того, какой тип свойства вы хотите сохранить в модели предметной области, будь то «строка», «логическое значение» или что угодно. Ключевой момент - положиться на -

get
{
  return _domainModel.Mode.ToUpper() == <corresponding domain property val>;
}

в свойстве GET вместо того, чтобы возвращать значение локального поля и НЕ устанавливать какое-либо значение в модели предметной области в случае, если "значение", которое входит в свойство SET, не истинно, иначе пусть модель предметной области будет иметь свое текущее значение

set
{
  _domainModel.Mode = (value == true) ? <domain property to set> : _domainModel.Mode;
}

Другой важный момент заключается в том, что этот тип привязки данных радиокнопок работает только тогда, когда для Binding.DataSourceUpdateMode установлено значение OnValidation, которое является значением по умолчанию. При изменении на OnPropertyChanged последовательность активации события свойств при переключении с одной кнопки на другую ведет себя таким образом, что не позволяет оценить правильное значение свойства для кнопки, на которую перемещается элемент управления. Но DataSourceUpdateMode практически не изменяется в обычных приложениях, и поэтому, к счастью, он будет работать для большинства приложений с ДВУМЯ или БОЛЬШЕ радиокнопок.

(Я видел, что этот вопрос получил хорошие отзывы, но ответа еще не было. Поэтому я подумал, что должен поделиться тем, что я наконец сделал, чтобы решить эту проблему.)

person Rajarshi    schedule 24.05.2010