Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Register Default TypeConverters through .net mechanism

Open tisis2 opened this issue 11 months ago • 0 comments

Hi there,

Is your feature request related to a problem? Please describe. as far as i see there is no way to find the default converters for IImage or FontFamily and others during runtime. in WPF all type convertions are registered through the TypeConverterAttribute. that leads to the fact that you can find the converter also during runtime. e.g. in the past i created a converter for WPF that would format a string with bound values and should be used as it would have been a input from xaml. since the type converters are not used when using bindings i created a converter that would do string format and convert to target type. for reference here:

public class StringFormatToTargetTypeConverter : IValueConverter, IMultiValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Convert(new object[] { value }, targetType, parameter, culture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    [Localizable(false)]
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter is null)
        {
            throw new ArgumentException("string format set as parameter");
        }
        
        var typeConverter = TypeDescriptor.GetConverter(targetType);
        if (typeConverter is null)
        {
            throw new ArgumentException($"no TypeConverter for target type found: {targetType.FullName}");
        }

        if (!typeConverter.CanConvertFrom(typeof(string)))
        {
            throw new ArgumentException($"TypeConverter '{typeConverter.GetType().FullName}' cannot convert from string");
        }

        var formatted = string.Format(parameter.ToString()!, values);
        return typeConverter.ConvertFrom(formatted);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

this is not possible in Avalonia since TypeDescriptor.GetConverter(targetType) would not always find the converter (e.g. BitmapTypeConverter for IImage). instead the type convertion for these type are done in the xaml loader here https://github.com/AvaloniaUI/Avalonia/blob/master/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs#L128. this makes it hard to write very generic converters like the above example. it would be needed to copy this mapping over to your project and resolve the correct converter on your own. what could later on lead to incompatibilities on future update when the list or logic changes.

Describe the solution you'd like use the typeconvertion mechanism of .net or provide a way to fetch the converter used for a type

maybe im missing anything or there is even another way to reach what i am looking for and you could point me to that. thanks for your help

tisis2 avatar Jul 14 '23 09:07 tisis2