Recently, I faced a scenario where I wanted to create a generic control template in WPF for a user control that refers to value converters dynamically in order to render parts of the control.
Depending on the enumeration passed as the parameter, converter is supposed to render different aspect of the object. The actual formatter is unknown at the base control level except for the enumeration.
Concrete implementation/usage of the control should specify the converter as its property. I tried doing this in XAML:
SomeProperty = {Binding Converter={Binding MyConverterProperty} }
The above will result in runtime exception as
Converter
property is not
DependencyProperty
within
BindingMarkupExtension
.
There are three ways of achieving the above:
1. Create a virtual converter and have object implement
IConvertable
:
One can declare
IConvertable
interface that provides a converter:
public interface IConvertable
{
IValueConverter Converter {get;}
}
and a "virtual" converter:
public class VirtualConverter : IValueConverter
{
public void Convert(object value, ....)
{
IValueConverter converter;
if ((value is IConvertible) && ((converter = (value as IConvertible) != null)))
{
converter.Convert(....);
}
throw new InvalidOperationException();
}
:
:
}
And now you can create a
static
resource of type
VirtualConverter
and use Binding normally specifying
VirtualConverter
as the converter.
2. Implement
IConvertible
but instead of creating Virtual converter, declare a markup extension that takes in
IConvertible
and returns
IValueConverter
. Then your markup will look like:
SomeProperty = "{Binding Converter={ConverterExtension Source={Binding}}}"
3. Use attached property to define
Converter
on an object rather than implementing
IConvertible
and specify it as converter in binding.
Happy coding!
Ashish