Как я могу применить MVVM и Команды в этой конкретной ситуации WPF? - PullRequest
0 голосов
/ 22 января 2010

У меня проблемы с шаблоном MVVM и командами в моем приложении WPF. Проблема не столько в шаблоне MVVM, сколько в том, что происходит в моем графическом интерфейсе. Я объясню ситуацию:

Мое приложение может DoStuff для некоторых файлов. У меня есть класс с функцией DoStuff(int limit). Мой пользовательский интерфейс имеет следующие элементы:

  • A Button DoStuffBtn для начала разбора.
  • A TextBox LimitTxt для заполнения лимита.
  • A CheckBox LimitChk для включения или отключения ограничения.

Когда вы "снимите галочку" LimitChk, тогда LimitTxt.Text = "" и LimitTxt.IsEnabled = false. Когда вы «отметите» LimitChk, затем LimitTxt.IsEnabled = false снова, но текст останется пустым, пока вы не заполните что-нибудь.

Я прочитал много учебных пособий по командам в WPF и MVVM, но я просто не могу вылить свое дело в эту форму. Пример, который я привел, на самом деле является лишь небольшой частью моего пользовательского интерфейса, но, похоже, я тоже не могу этого делать.

Я продолжаю сталкиваться с такими вопросами, как:

  • Нужно ли мне два Commands для LimitChk (включить и отключить) или только одно (переключить)?
  • Если я свяжу int с LimitTxt, что произойдет, если я сделаю его пустым и отключу его?
  • Это простой способ использовать DoStuff(Int32.Parse(LimitTxt.Text)) при нажатии DoStuffBtn?
  • Если я использую две команды для LimitChk, что произойдет с функцией CanExecute() для ICommand, которая определяет, включен ли LimitChk?

Итак, главный вопрос: как описанная мной ситуация вписывается в красивый шаблон с использованием команд в WPF?

Некоторые ссылки на WPF, команды и MVVM, на которые я смотрел:


Насколько я понимаю, я должен максимально избегать использования пользовательского интерфейса. Даже такие вещи, как пользовательский интерфейс, влияющий на пользовательский интерфейс. То есть снятие отметки LimitChk отключает LimitText. Тем не менее, я думаю, что я должен держать разницу между информацией, связанной с пользовательским интерфейсом и действиями, и вещами, которые на самом деле имеют отношение к фактической работе, которая должна быть сделана.

Ответы [ 2 ]

3 голосов
/ 22 января 2010

Я думаю, что вы запутались ... вам не нужны никакие команды, вы можете просто использовать привязки.

  • Нужно ли две команды для LimitChk (включить и отключить) или только одну (переключить)?

Тебе ничего не нужно. Просто создайте свойство LimitEnabled в вашей ViewModel и привяжите к нему CheckBox (IsChecked="{Binding LimitEnabled}")

  • Если я связываю int с LimitTxt, что произойдет, если я сделаю его пустым и отключу его?

Отключение не имеет никакого эффекта. Если вы сделаете TextBox пустым, привязка не будет выполнена, потому что пустая строка не может быть преобразована в целое число (по крайней мере, с помощью конвертера по умолчанию)

  • Это простой способ использовать Parse (Int32.Parse (LimitTxt.Text)) при нажатии ParseBtn?

Вам не нужно. Просто создайте свойство Limit в вашей ViewModel и привяжите к нему TextBox. Возможно, вы захотите добавить ExceptionValidationRule к Binding, чтобы выделить недопустимый ввод.

Кнопка не нужна, анализ будет выполняться автоматически, когда TextBox потеряет фокус (если вы используете значение по умолчанию UpdateSourceTrigger). Если вы хотите настроить способ его анализа, вы можете создать собственный конвертер для использования в привязке.

1 голос
/ 22 января 2010

Только некоторые мысли высокого уровня, оставляя без внимания лишние вещи, такие как цвет и атрибуты выравнивания, WrapPanels и т. Д.

Ваш ViewModel имеет несколько свойств:

public bool? LimitIsChecked { get; set; }
public bool LimitTextIsEnabled { get; set; }  //to be expanded, below
public ICommand ParseCommand { get; private set; } // to be expanded, below
public string LimitValue { get; set; } // further explanation, below

Ваш XAML имеет определения CheckBox и TextBox, например:

<CheckBox Content="Limit Enabled" IsChecked="{Binding LimitIsChecked}" />
<TextBox Text="{Binding LimitValue}" IsEnabled="{Binding LimitIsEnabled}" />
<Button Content="Parse" Command="{Binding ParseCommand}" />

Вы захотите инициализировать ParseCommand примерно так:

this.ParseCommand = new DelegateCommand<object>(parseFile);

Теперь давайте также заполним это свойство LimitTextIsEnabled:

public bool LimitTextIsEnabled {
    // Explicit comparison because CheckBox.IsChecked is nullable.
    get { return this.LimitIsChecked == true; }
    private set { }
}

Ваш метод parseFile затем передаст значение свойства LimitValue логике, выполняющей фактический анализ.

Я объявил свойство LimitValue здесь как строку, чтобы избежать загромождения кода явным конвертером или другим кодом проверки. Вы можете решить, что проверка / преобразование «LimitValue является действительным int» несколькими различными способами.

Конечно, я не реализовал это полностью, но я хотел обрисовать схему, в которой вы не используете команды для обновления состояния других виджетов. Вместо этого свяжите эти атрибуты со свойствами, которые управляются в вашей ViewModel.

...