Created
October 12, 2022 10:08
-
-
Save hacklex/a35f960ed184442d26395f6e591e1ada to your computer and use it in GitHub Desktop.
Universal Color Converter for Avalonia
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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