IValueConverter with MarkupExtension
The only (slight) advantage that the markup extension is providing in this case is more concise XAML syntax.
Instead of this:
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
...
{Binding SomeBooleanProperty, Converter={StaticResource BooleanToVisibilityConverter}}
you can have this:
{Binding SomeBooleanProperty, Converter={my:BoolToVisibilityConverter}}
In my opinion it's not really worth it. If you were that bothered about saving keystrokes you could just shorten the key used to reference the converter:
<BooleanToVisibilityConverter x:Key="btvc" />
...
{Binding SomeBooleanProperty, Converter={StaticResource my:btvc}}
As the ProvideValue
method of the markup extension is an instance method, it can only be called once an instance of the class has been created. As the class is both a markup extension and a converter, both variants of the code will create a converter each time. The only difference is that the first variant will always return the same converter: it won't however, stop another converter from being created.
One massive advantage of using MarkupExtension
which I have never seen being used online is the fact it can allow you pass values to the converter which could be used as argument or return values, for example:
public class CustomNullToVisibilityConverter : MarkupExtension, IValueConverter
{
public object NullValue { get; set; }
public object NotNullValue { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return NullValue;
return NotNullValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Usage:
...
Visibility="{Binding Property,
Converter={cnv:CustomNullToVisibilityConverter
NotNullValue=Visible, NullValue=Collapsed}}" />
...
Be sure to reference the namespace of the converter in the .xaml
.
Edit:
One thing I forgot to mention is that yes you are correct in the fact that this method would create a new instance of the converter each time it's used which is one downside.
However there nothing to stop you adding a converter with MarkupExtension
to a resource dictionary - that way it will only be instanced once. Like so:
<cnv:CustomNullToVisibilityConverter x:Key="NullToVisibilityConverter"
NotNullValue=Visible, NullValue=Collapsed />
...
Visibility="{Binding Property, Converter={StaticResource NullToVisibilityConverter}" />
...