установить текст данных кнопки для нескольких элементов - PullRequest
1 голос
/ 11 марта 2010

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

Я связал текст данных моего Баттона следующим образом:

DataContext="{Binding ElementName=txtEmail}"

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

Как установить привязку к нескольким текстовым полям?

Ответы [ 2 ]

3 голосов
/ 11 марта 2010

Вы не можете, по крайней мере, не напрямую. Вы можете использовать MultiBinding со всеми желаемыми текстовыми полями в качестве входных данных, но вам нужно будет предоставить IMultiValueConverter для «объединения» различных текстовых полей в один объект (например, список):

<Button>
  <Button.DataContext>
    <MultiBinding Converter="{StaticResource ListMaker}">
      <Binding ElementName="txtEmail" />
      <Binding ElementName="txtFirstName" />
      <Binding ElementName="txtLastName" />
    </MultiBinding>
  </Button.DataContext>
</Button>

И именно этот результирующий объект списка будет передан вашему триггеру, так что вы не сможете напрямую получить доступ к свойству Validation.HasError: вашему DataTrigger также понадобится преобразователь, который преобразует объект списка. в логическое значение, указывающее, установлено ли Validation.HasError для чего-либо в списке. На этом этапе вы можете просто забыть о триггерах и связать IsEnabled с помощью MultiBinding:

<Button>
  <Button.IsEnabled>
    <MultiBinding Converter="{StaticResource AllFalse}">
      <Binding Path="(Validation.HasError)" ElementName="txtEmail" />
      <Binding Path="(Validation.HasError)" ElementName="txtFirstName" />
      <Binding Path="(Validation.HasError)" ElementName="txtLastName" />
    </MultiBinding>
  </Button.DataContext>
</Button>

(Здесь преобразователь AllFalse возвращает значение true, если все входные данные имеют значение false, и значение false, если любой вход имеет значение true.)

Однако лучший подход может заключаться в том, чтобы вместо привязки Button непосредственно к другим элементам пользовательского интерфейса иметь ваш объект данных - тот же объект, к которому привязаны ваши текстовые поля - предоставить свойство IsValid (с подходящими уведомлениями об изменениях). ), и привяжите свою кнопку к этому:

<Button IsEnabled="{Binding IsValid}" />

Это перемещает вас к решению в стиле MVVM, которое помогает с такими вещами, как тестируемость (например, легко создавать тесты для свойства IsValid; гораздо сложнее создавать тесты для Button.IsEnabled).

0 голосов
/ 11 марта 2010

Для подхода MVVM вы можете попробовать реализовать командный маршрутизатор из ICommand.

<Button Command="{Binding Path=Commands.MyButtonCommand}" Style="{StaticResource MyButtonStyle}" ></Button>

где свойство Commands является частью ViewModel. Затем вы можете контролировать, какие функции реализует команда, а также включена она или нет. Тестирование тогда намного проще.

...