Связывание данных радиокнопок Windows Forms - PullRequest
2 голосов
/ 15 февраля 2010

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

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

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

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

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

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

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

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

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

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

Существует простое решение этой проблемы с помощью метода, подобного -

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

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

1 Ответ

6 голосов
/ 24 мая 2010

Класс «Мой домен / Бизнес-модель» содержит свойство «Mode» типа «string». Для режимов AUTO / MANUAL / IMPORT свойство Mode должно содержать «A» / «M» / «I» соответственно. Моя модель предметной области получена моим классом Presentation Model через конструктор в Presentation Model.

Класс 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, а не в возврате значения локального поля и в значение NOT TO для установки какого-либо значения в модели предметной области, если «значение», входящее в свойство SET, не TRUE, иначе пусть модель предметной области имеет свое текущее значение

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

Другим важным моментом является то, что этот тип привязки радиокнопок работает только тогда, когда для Binding.DataSourceUpdateMode установлено значение OnValidation, которое используется по умолчанию. При изменении на OnPropertyChanged последовательность срабатывания событий свойств при переключении с одной кнопки на другую ведет себя таким образом, что не позволяет оценить правильное значение свойства для кнопки, к которой перемещается элемент управления. Но DataSourceUpdateMode практически не изменяется в обычных приложениях, и, к счастью, это будет работать для большинства приложений с двумя или более радиокнопками.

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

...