WPF: Как использовать свойство объекта в качестве параметра конвертера IValueConverter.ConverterParameter
Допустим, у нас есть объект MyObject со свойствами MyData и MyProperty. Для его отображения в графическом пользовательском интерфейсе, построенном на XAML, мы хотим использовать эти два свойства, преобразовав MyData с помощью IValueConverter, а MyProperty использовать в качестве параметра конвертера ConverterParameter. Реально ли это?
Например, мы хотим отобразить в групповом контейнере GroupBox (или в любом другом контейнере, которое имеет свойство Content, например, ScrollViewer) содержимое свойства MyData, и управляющим параметром будет MyProperty. То есть мы хотим получить следующий код:
<GroupBox DataContext="{Binding MyObject}" Content="{Binding MyData, Converter={StaticResource MyConverter}, ConverterParameter={Binding MyProperty}}" />
Естественно, где-то выше, в разделе ресурсов, мы создали ресурс с идентификатором MyConverter.
Если мы напишем такую разметку, парсер XAML остановится на этом месте и сообщит, что ConverterParameter должен быть свойством зависимости DependencyProperty, а наше свойство MyProperty не является свойством зависимости. К сожалению, использовать таким образом обычное свойство не получится.
Но можно достичь аналогичного результата, прибегнув к такому решению: использовать вместо обычного конвертера IValueConverter – конвертер IMultiValueConverter, который позволяет передавать из XAML в фоновый код несколько свойств. Таким методом нашу задачу можно решить так:
<GroupBox DataContext="{Binding MyObject}"> <GroupBox.Style> <Style TargetType="GroupBox"> <Setter Property="Content"> <Setter.Value> <MultiBinding Converter="{StaticResource MyConverter}"> <Binding Path="MyData" /> <Binding Path="MyProperty" /> </MultiBinding> </Setter.Value> </Setter> </Style> </GroupBox.Style> </GroupBox>
В этом случае, наш класс, который реализует интерфейс IMultiValueConverter, получит массив объектов типа Object. В данном случае это будут два объекта, получить которые можно по индексу: value[0] и value[1], а затем привести их типы к типам исходных MyData и MyProperty, соответственно.
Кстати, в качестве параметра конвертера ConverterParameter можно использовать не только числа, а все базовые типы .NET из пространства имён System.
Для этого импортируем в XAML это пространство имён, назначив ему префикс, например, sys:
<Page xmlns:sys="clr-namespace:System;assembly=mscorlib" [другие пространства имён] … >
А затем укажем тип параметра конвертера так:
<GroupBox DataContext="{Binding MyObject}"> <GroupBox.Content> <Binding Converter="{StaticResource MyConverter}"> <Binding.ConverterParameter> <sys:Int32>125</sys:Int32> </Binding.ConverterParameter> </Binding> </GroupBox.Content> … </GroupBox>