Skip to content

Instantly share code, notes, and snippets.

@hacklex
Created October 12, 2022 10:08
Show Gist options
  • Select an option

  • Save hacklex/a35f960ed184442d26395f6e591e1ada to your computer and use it in GitHub Desktop.

Select an option

Save hacklex/a35f960ed184442d26395f6e591e1ada to your computer and use it in GitHub Desktop.
Universal Color Converter for Avalonia
using System;
using System.Globalization;
using Avalonia;
using Avalonia.Data;
using Avalonia.Media;
namespace Avalonia.Data.Converters;
public class ColorConverter : IValueConverter
{
public static object GetColor(object? value)
{
var x = value;
if (x == null) return AvaloniaProperty.UnsetValue;
if (x is Color r) return r;
if (x is int t) return Color.FromUInt32(unchecked((uint)t));
if (x is uint u) return Color.FromUInt32(u);
if (x is SolidColorBrush scb) return scb.Color;
if (x is Pen p && p.Brush is SolidColorBrush pscb) return pscb.Color;
if (Color.TryParse(x.ToString(), out Color c))
{
return c;
}
return AvaloniaProperty.UnsetValue;
}
private static Dictionary<Color, SolidColorBrush> _solidBrushes = new();
private static Dictionary<Color, Pen> _solidPens = new();
static TValue GetOrCreate<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TKey key,
Func<TKey, TValue> factory) where TKey : notnull
{
if (dictionary.TryGetValue(key, out var rv))
return rv;
return dictionary[key] = factory(key);
}
static Pen GetPen(Color c) => GetOrCreate(_solidPens, c, c => new Pen(GetBrush(c)));
static Brush GetBrush(Color c) => GetOrCreate(_solidBrushes, c, c => new SolidColorBrush(c));
public static object ConvertColor(Color color, Type targetType)
{
if (targetType == typeof(string)) return color.ToString();
if (targetType == typeof(int)) return unchecked((int)color.ToUint32());
if (targetType == typeof(uint)) return color.ToUint32();
if (targetType == typeof(Color)) return color;
if (targetType == typeof(Brush)) return GetBrush(color);
if (targetType == typeof(Pen)) return GetPen(color);
return AvaloniaProperty.UnsetValue;
}
public static object Convert(object? value, Type targetType)
{
var colorVal = GetColor(value);
if (!(colorVal is Color c))
return new BindingNotification(
new InvalidCastException($"{value} is not coercible to a valid color value"),
BindingErrorType.Error);
return ConvertColor(c, targetType);
}
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
=> Convert(value, targetType);
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> Convert(value, targetType);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment