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>
