如何对组合框中可选择的项目应用限制

时间:2011-08-20 15:52:15

标签: c# winforms view model combobox

我正在开发一个c#winforms应用程序。除其他外,底层模型具有StartTime和EndTime DateTime属性,限制条件是StartTime必须在EndTime之前。为了让用户能够更改这些属性,我将两个组合框填充样本值以供选择,并将每个组合框挂起,以便选择另一个值将更改模型中的相应属性。

这种方法的问题在于它允许用户尝试选择非法值。理想情况下,我希望当用户选择某个StartTime值时,可能的EndTime值被限制,因此无法在此之前选择EndTime值。实现这一目标的一种方法是使用新的合法值填充结束组合框,然后选择之前的组合。这将要求我的SelectedIndexChanged事件处理程序暂时关闭,否则重新选择EndTime将导致无限循环,分别在填充/重新选择StartTime和EndTime组合框之间交替。

另一种解决方案是保留所有样本值,然后还原用户尝试进行的任何非法更改,但用户可以尝试选择非法值这一事实对我没有吸引力。我不喜欢暂时禁用事件处理程序,因为它看起来不干净,但我看不到任何更好的解决方案。您有任何建议或改进吗?

3 个答案:

答案 0 :(得分:1)

我会添加一个专门为您的UI场景设计的类(有些人称之为“ModelView”)。 它是数据模型和UI之间的代理。代理的目的是在编辑期间保持不变(startDate< endDate)延迟对模型的更改,完成编辑。此时,更改将应用​​于基础数据对象。

      class MyDataObjectProxy: IPropertyChangedNotification
      {
          MyDataObjectProxy(MyDataObject model)
         {
             _model = model;
             _editedStartDate = model.StartDate;
             _editedEndDate = model.EndDate;
         }


          MyDataObject _model;

          public DateTime StartDate
          {
             get
             {
                 return Math.Min(editedStartDate, editedEndDate); 
             }

             set 
             {
                 _editedStartDate = value; 
                 RaisePropertyChanged("StartDate");
                 RaisePropertyChanged("EndDate");
             }
          }  

          public DateTime EndDate
          {
             get
             {
                 return Math.Max(editedStartDate, editedEndDate); 
             }

             set 
             {
                 _editedEndDate = value; 
                 RaisePropertyChanged("StartDate");
                 RaisePropertyChanged("EndDate");
             }
          }  


          DateTime _editedStartDate;
          DateTime _editedEndDate;


          public void ApplyChanges()
          {
               DateTime start = StartDate;
               DateTime end = EndDate;

              _data.StartDate = start;
              _data.EndDate = end;
          }

答案 1 :(得分:1)

有一次你打开你的表格:

  1. StartDate 设置为某个初始值,让我们说今天
  2. EndDate 设置为某个初始值,明天(禁用)
  3. 添加全局boolean变量bool SilentInvoke = false;
  4. 订阅SelectedIndexChanged以了解开始和结束用户界面控件。
  5. 在每个selectedindex更改事件的开头,代码或多或少都是这样的:

    if( SilentInvoke)
    {
          SilentInvoke=false;
          return;
    }
    
  6. 用户更改 StartDate ,启用 EndDate

  7. 用户更改 EndDate ,如果在 StartDate 之前,请通知用户并将其重置为初始值,但在生成SilentInvoke=true;之前
  8. 用户总是有可能返回并再次更改 StartDate ,但您必须拥有在最终请求之前验证数据的某处验证方法。

    首先,在让用户自由决定并在实际请求之前进行验证之后,为用户提供一种指南(启用启用,结束禁用)。

答案 2 :(得分:1)

更改组合框选择时,请执行以下操作:

  1. 设置一个标志变量,可用于防止重新进入此组合框的事件处理程序(A),
  2. 考虑刚在此组合框(A)中选择的新日期,将所有合法日期重新加载到另一个组合框(B)。
  3. 将另一个组合框(B)中的日期设置为已选择的日期(替换日期之前),如果在(B)中选择了日期,并且组合框中的新日期是合法的( A)
  4. 重置旗帜。