Множественная привязка в WPF
Опубликовано в Полезные советы
Как сделать привязку (binding) визуального элемента в WPF к нескольким свойствам? Для этого существует так назваемая множественная привязка. Вот пример разметки, который использует свойства FirstName и LastName некоторого объекта для вывода их посредством одного элемента TextBlock:
<TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{}{0} {1}"> <Binding Path="FirstName" /> <Binding Path="LastName" /> </MultiBinding> </TextBlock.Text> </TextBlock>
Формат вывода текста определяется атрибутом StringFormat. Обратите внимание на пустые фигурные скобки в начале определения формата строки. Они подсказывают парсеру XAML, что здесь используется привязка.
Добиться подобного же результата можно также с помощью конвертера MultiValueConverter, который принимает несколько значений. Вот тот же пример, но с использованием конвертера. Сначала необходимо написать класс самого конвертера:
Public Class PersonNameMultiConverter Implements IMultiValueConverter Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert If (values.Length > 0) Then Dim firstName As String = values(0).ToString() Dim lastName As String = values(1).ToString() Return firstName & " " & lastName End If Return String.Empty End Function Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack Throw New NotImplementedException() End Function End Class
Далее в начале XAML файла, в котором планируется использовать данный конвертер, в разделе ресурсов необходимо объявить соответствующий ресурс:
<conv:PersonNameMultiConverter x:Key="personNameMultiConverter" />
И далее создадим текстовое поле и добавим ему привязку:
<TextBlock> <TextBlock.Text> <MultiBinding Converter="{StaticResource personNameMultiConverter}"> <Binding Path="FirstName" /> <Binding Path="LastName" /> </MultiBinding> </TextBlock.Text> </TextBlock>
Гораздо больше кода потребовалось, чем в первом варианте, верно? Однако преимуществом последнего метода является то, что конвертеру можно передавать сложные объекты и производить с ними какую-либо серьёзную обработку, что попросту невозможно при использовании первого варианта.