как применить ограничения, какие элементы выбираются в выпадающем списке - PullRequest
0 голосов
/ 20 августа 2011

Я занимаюсь разработкой приложения на C # winforms. Базовая модель имеет, среди прочего, свойство StartTime и EndTime DateTime, с тем ограничением, что StartTime должен предшествовать EndTime. Чтобы дать пользователю возможность изменять эти свойства, я заполняю два комбинированных списка выборочными значениями и подключаю каждый комбинированный список, так что выбор другого значения изменит соответствующее свойство в модели.

Проблема этого подхода заключается в том, что он позволяет пользователю попытаться выбрать недопустимое значение. В идеале мне бы хотелось, чтобы, когда пользователь выбирает определенное значение StartTime, возможные значения EndTime ограничиваются, так что невозможно выбрать значения EndTime раньше, чем это. Один из способов добиться этого - заполнить конечный комбинированный список новыми допустимыми значениями, а затем выбрать то, что было ранее. Для этого потребуется, чтобы мой обработчик событий SelectedIndexChanged был временно отключен, поскольку в противном случае повторный выбор EndTime вызовет бесконечный цикл, чередующийся между заполнением / повторным выбором комбинированных списков StartTime и EndTime соответственно.

Другое решение - сохранить все значения выборок, а затем отменить любые недопустимые изменения, которые пользователь пытается внести, но тот факт, что пользователь может попытаться выбрать недопустимые значения, меня не привлекает. Мне не нравится временно отключать обработчик событий, так как он не выглядит чистым, но я не вижу более эффективных решений. У вас есть предложения или улучшения?

Ответы [ 3 ]

1 голос
/ 20 августа 2011

Один раз, открывая форму, вы:

  1. Установите StartDate на некоторое начальное значение, скажем сегодня
  2. Установите EndDate к некоторому начальному значению, скажем, завтра (отключено)
  3. Добавить глобальную boolean переменную bool SilentInvoke = false;
  4. Подписаться на SelectedIndexChanged для элементов управления Start и End UI.

    В начале каждого измененного события selectedindex код примерно такой:

    if( SilentInvoke)
    {
          SilentInvoke=false;
          return;
    }
    
  5. Пользовательские изменения StartDate , включение EndDate .

  6. Пользовательские изменения EndDate , если он до StartDate , уведомить пользователя и сбросить его до начального значения, но перед make SilentInvoke=true;

Всегда существует вероятность того, что пользователь вернется и изменит StartDate снова, но у вас должен быть где-то метод проверки, который проверяет данные перед окончательным запросом.

Сначала вы даете пользователю вид руководства (начало включено, конец отключен), а затем оставляете пользователя свободным для принятия решения и проверки перед фактическим запросом.

1 голос
/ 21 августа 2011

Когда изменяется поле со списком, сделайте это:

  1. Установите переменную флага, которую вы можете использовать, чтобы предотвратить повторный ввод в обработчик событий для этого комбинированного списка (A), и
  2. Перезагрузите другой комбинированный список (B) со всеми допустимыми датами, учитывая новую дату, только что выбранную в этом комбинированном списке (A).
  3. Установите дату в другом поле со списком (B) на дату, которая уже была выбрана (до того, как даты были заменены), если в (B) была выбрана дата, и если она является допустимой с новой датой в поле со списком ( A)
  4. Сброс флага.
1 голос
/ 20 августа 2011

Я бы добавил класс (некоторые назвали бы его «ModelView»), разработанный специально для вашего сценария пользовательского интерфейса. Это своего рода прокси между моделью данных и пользовательским интерфейсом. Назначение прокси-сервера - поддерживать инвариант (startDate

      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;
          }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...