Should IValueConverter be part of the .NET Standard?
It seems so since it is identical in WPF, UWP and Xamarin Forms
Maybe. With WPF coming to .NET Core this seems like a good time to consider it for 2.1.
It doesn't seem to exist in .NET Standard 2.1. I guess it didn't make it?
Correct 馃槥
This is the interim solution, if anyone is interested. Our library code (used by WPF and asp.net core) needed the converters to be in the platform agnostic library implementing .net standard / core.
Define the interfaces. Make them as close as possible to WPF.
public interface IValueConverterStandard
{
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
public interface IMultiValueConverterStandard
{
object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
}
internal class NamedObject
{
private string _name;
public NamedObject(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(name);
}
_name = name;
}
public override string ToString()
{
if (_name[0] != '{')
{
_name = string.Format(CultureInfo.InvariantCulture, "{{{0}}}", new object[1]
{
_name
});
}
return _name;
}
}
public static class DataBinding
{
public static readonly object DoNothing = new NamedObject("Binding.DoNothing");
public static readonly object UnsetValue = new NamedObject("DependencyProperty.UnsetValue");
public static readonly object[] DoNothingArr = new object[] { DoNothing };
}
Implement the interface:
public class ConverterFeatureSetName : IValueConverterStandard
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var str = value as string;
return string.IsNullOrEmpty(str) ? "[Default]" : str;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DataBinding.DoNothing;
}
}
Implement a WPF base converter for all "standard" converters. WPF base converter instantiates a standard converter and stores it in a field/property. It then relays Convert/ConvertBack methods to the standard converter. Results are converted to DependencyProperty.UnsetValue / Binding.DoNothing
public class BaseConverter<T> : IValueConverter where T : IValueConverterStandard, new()
{
protected T Converter { get; }
public BaseConverter()
{
Converter = new T();
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var retval = Converter.Convert(value, targetType, parameter, culture);
if (retval == DataBinding.UnsetValue)
return DependencyProperty.UnsetValue;
return retval;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var retval = Converter.ConvertBack(value, targetType, parameter, culture);
if (retval == DataBinding.DoNothing)
return Binding.DoNothing;
return retval;
}
}
public class BaseMultiValueConverter<T> : IMultiValueConverter where T : IMultiValueConverterStandard, new()
{
protected T Converter { get; }
public BaseMultiValueConverter()
{
Converter = new T();
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var retval = Converter.Convert(values, targetType, parameter, culture);
if (retval == DataBinding.UnsetValue)
return DependencyProperty.UnsetValue;
return retval;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
var retval = Converter.ConvertBack(value, targetTypes, parameter, culture);
if (retval.Length > 0 && retval[0] == DataBinding.DoNothing)
return new object[] { Binding.DoNothing };
return retval;
}
}
Implement one liner classes for use in XAML
public class ConverterFeatureSetName : BaseConverter<DataConverters.ConverterFeatureSetName> { }
Once .net standard / core supports IValueConverter , it would be easy enough to replace references to IValueConverterStandard with IValueConverter. Everything else can remain as is.
Most helpful comment
This is the interim solution, if anyone is interested. Our library code (used by WPF and asp.net core) needed the converters to be in the platform agnostic library implementing .net standard / core.
Library
Define the interfaces. Make them as close as possible to WPF.
Implement the interface:
Consuming library (WPF)
Implement a WPF base converter for all "standard" converters. WPF base converter instantiates a standard converter and stores it in a field/property. It then relays Convert/ConvertBack methods to the standard converter. Results are converted to DependencyProperty.UnsetValue / Binding.DoNothing
Implement one liner classes for use in XAML
Once .net standard / core supports IValueConverter , it would be easy enough to replace references to IValueConverterStandard with IValueConverter. Everything else can remain as is.