【问题标题】:How can I enable/disable some controls among multiple controls under various different conditions?如何在各种不同条件下启用/禁用多个控件中的某些控件?
【发布时间】:2009-04-11 18:58:06
【问题描述】:

如何在各种不同条件下启用/禁用多个控件中的某些控件?

假设有一个带有一些行的 GUI,每行代表一个人。还有一些按钮,代表一些动作,比如“站、坐、走、跳、吃、看电视、醒来、睡觉”,还有一些条件,比如如果有人坐着,他可以吃东西和看电视(即启用那些按钮)但不能跳跃(禁用它),如果有人站着他就不能睡觉,等等。

此外,状态变化不仅仅基于按钮点击。比如,他可能会在一段时间后自己醒来,或者说,在他吃完饭后。

似乎最天真的方法是编写.Enabled = true/false; 代码为n 个状态X m 次按钮,并检查每个用户或非用户触发的状态更改。有没有更好/更快/更不容易出错的方法来做到这一点?

还有,这些东西叫什么?

【问题讨论】:

    标签: c# user-interface


    【解决方案1】:

    这取决于您使用的是 WPF 还是 WinForms。

    WPF 允许您对 Enabled 属性进行数据绑定,因此您可以声明性地说明何时应该启用它,并且只要触发正确的属性更改事件,它就会发生。

    使用 WinForms,是的,设置 .Enabled 是可行的方法。最简单的事情是编写一种名为例如的方法。 UpdateEnabled() 根据您的规则更新您所有控件上的 Enabled(如果跳跃,则应禁用 btnEat),然后在状态更改时调用该方法。

    由于并非所有状态更改都响应 GUI 事件,因此您可能需要一个模型对象来维护状态并在状态更改时触发事件。然后,只要该事件触发,您就可以调用 UpdateEnabled() 方法来根据新状态刷新 GUI。

    如果您的需求很简单,这就是您需要做的所有事情。如果您的应用变得更复杂,您可能需要研究诸如 Model-View-Presenter 之类的模式——Presenter 将是基于当前状态知道哪些操作已启用以及哪些操作已禁用的类。

    【讨论】:

      【解决方案2】:

      我会将Enabled 属性绑定到类的Can*CanWalkCanJump 等)属性,实现INotifyPropertyChanged,并在对象的状态更改时检查每个可能受影响的属性。

      这种方法的优点是 Person 类和 UI 不需要相互了解任何信息。此外,实现INotifyPropertyChanged 消除了在每次状态更改后对类属性的多余轮询。

      如果您不想使用复杂的数据绑定,您仍然可以监听PropertyChanged 事件并手动更新 UI。

      例如:

      partial class Person : INotifyPropertyChanged
      {
          bool _IsSleeping, _IsSitting;
      
          public bool IsSleeping 
          { 
              get { return _IsSleeping; } 
              set 
              {
                  if(_IsSleeping != value)
                  {
                      _IsSleeping = value;
                      OnIsSleepingChanged();
                  }
              }
          }
      
          public bool IsSitting 
          { 
              get { return _IsSitting; } 
              set 
              {
                  if(_IsSitting != value)
                  {
                      _IsSitting = value;
                      OnIsSittingChanged();
                  }
              }
          }
      
          protected virtual void OnIsSleepingChanged()
          {
              NotifyPropertyChanged("IsSleeping");
              CheckCanJumpChanged();
          }
      
          protected virtual void OnIsSittingChanged()
          {
              NotifyPropertyChanged("IsSitting");
              CheckCanJumpChanged();
          }
      
          bool CanJump_Old;
          public bool CanJump { get { return !(IsSleeping || IsSitting); } }
      
          void CheckCanJumpChanged()
          {
              if(CanJump != CanJump_Old)
              {
                  CanJump_Old = CanJump;
                  NotifyPropertyChanged("CanJump");
              }
          }
      
          //INotifyPropertyChanged helper method
          private void NotifyPropertyChanged(String prop)
          {
              var hand = PropertyChanged;
              if (hand != null)
                  hand(this, new PropertyChangedEventArgs(prop));
          }
      }
      

      【讨论】:

        【解决方案3】:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-12-07
          • 2015-11-12
          • 1970-01-01
          • 1970-01-01
          • 2016-04-13
          • 2010-12-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多