【问题标题】:Windows Forms radiobutton data bindingWindows 窗体单选按钮数据绑定
【发布时间】:2011-01-17 01:32:44
【问题描述】:

我正在遵循Martin Fowler 建议的presentation model 设计模式,用于我在 Windows 窗体项目中的 GUI 架构。

"Presentation Model 的本质是一个完全独立的类,它表示 UI 窗口的所有数据和行为,但没有任何用于在屏幕上呈现该 UI 的控件。视图然后简单地将演示模型的状态投影到玻璃上......” - Martin Fowler

除了将 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,因此,更新任何数据/域对象属性会自动更新我的 UI 控件,这不是问题。

在 StackOverflow 问题 How do I use databinding with Windows Forms radio buttons? 中有一个很好的绑定两个单选按钮的例子,但是我在用三个按钮实现相同的时候缺少链接。我的单选按钮行为非常不稳定。

我希望我能够合理地解释它。我实际上很着急,无法在帖子上发布详细的代码,但感谢您在这方面的任何帮助。

有一个简单的方法可以解决这个问题,方法是公开一个类似的方法 -

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

可以从 UI 单选按钮的“CheckedChanged”事件中调用,并在业务对象上完美设置“SelectedMode”,但我需要扩展限制以验证这是否可以通过 DataBinding 完成。

【问题讨论】:

    标签: winforms data-binding radio-button


    【解决方案1】:

    My Domain/Business Model 类包含一个类型为“string”的“Mode”属性。对于 AUTO/MANUAL/IMPORT 模式,Mode 属性应分别包含“A”/“M”/“I”。我的领域模型由我的 Presentation Model 类通过 Presentation Model 中的构造函数接收。

    我的演示模型类包含三个布尔变量 “IsAutoMode”、“IsManualMode”、“IsImportMode”。这些布尔变量将用于 DataBinding 表单上的单选按钮。这些布尔属性的 GET/SET 进行了一些扩展,以处理更新域模型中的相应属性(“模式”)。注意下面展示模型类中的属性 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 中的“值”不是 TRUE,否则让域模型具有其当前值

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

    另一个重要的一点是,这种类型的单选按钮数据绑定仅在 Binding.DataSourceUpdateMode 设置为默认值 OnValidation 时才有效。如果更改为OnPropertyChanged 属性的事件触发顺序,当从一个按钮切换到另一个按钮时,其行为方式会阻止评估控件移动到的按钮的正确属性值。但是 DataSourceUpdateMode 在普通应用程序中几乎没有变化,因此幸运的是,这适用于大多数具有两个或更多单选按钮的应用程序。

    (我看到这个问题得到了很好的关注,但还没有发布答案。所以我想我应该分享一下我最终为解决这个问题所做的工作。)

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      相关资源
      最近更新 更多