37 changed files with 249 additions and 444 deletions
@ -0,0 +1,84 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Collections; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml.Converters; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Styling; |
|||
using Avalonia.Controls.Templates; |
|||
|
|||
namespace Avalonia.Markup.Xaml |
|||
{ |
|||
/// <summary>
|
|||
/// Maintains a repository of <see cref="TypeConverter"/>s for XAML parsing on top of those
|
|||
/// maintained by <see cref="TypeDescriptor"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The default method of defining type converters using <see cref="TypeConverterAttribute"/>
|
|||
/// isn't powerful enough for our purposes:
|
|||
///
|
|||
/// - It doesn't handle non-constructed generic types (such as <see cref="AvaloniaList{T}"/>)
|
|||
/// - Type converters which require XAML features cannot be defined in non-XAML assemblies and
|
|||
/// so can't be referenced using <see cref="TypeConverterAttribute"/>
|
|||
/// - Many types have a static `Parse(string)` method which can be used implicitly; this class
|
|||
/// detects such methods and auto-creates a type converter
|
|||
/// </remarks>
|
|||
public static class AvaloniaTypeConverters |
|||
{ |
|||
private static Dictionary<Type, Type> _converters = new Dictionary<Type, Type>() |
|||
{ |
|||
{ typeof(AvaloniaList<>), typeof(AvaloniaListConverter<>) }, |
|||
{ typeof(AvaloniaProperty), typeof(AvaloniaPropertyTypeConverter) }, |
|||
{ typeof(IBitmap), typeof(BitmapTypeConverter) }, |
|||
{ typeof(IList<Point>), typeof(PointsListTypeConverter) }, |
|||
{ typeof(IMemberSelector), typeof(MemberSelectorTypeConverter) }, |
|||
{ typeof(Selector), typeof(SelectorTypeConverter) }, |
|||
{ typeof(TimeSpan), typeof(TimeSpanTypeConverter) }, |
|||
{ typeof(WindowIcon), typeof(IconTypeConverter) }, |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Tries to lookup a <see cref="TypeConverter"/> for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <returns>The type converter.</returns>
|
|||
public static Type GetTypeConverter(Type type) |
|||
{ |
|||
if (_converters.TryGetValue(type, out var result)) |
|||
{ |
|||
return result; |
|||
} |
|||
|
|||
// Converters for non-constructed generic types can't be specified using
|
|||
// TypeConverterAttribute. Allow them to be registered here and handle them sanely.
|
|||
if (type.IsConstructedGenericType && |
|||
_converters.TryGetValue(type.GetGenericTypeDefinition(), out result)) |
|||
{ |
|||
return result?.MakeGenericType(type.GetGenericArguments()); |
|||
} |
|||
|
|||
// If the type isn't a primitive or a type that XAML already handles, but has a static
|
|||
// Parse method, use that
|
|||
if (!type.IsPrimitive && |
|||
type != typeof(DateTime) && |
|||
type != typeof(Uri) && |
|||
ParseTypeConverter.HasParseMethod(type)) |
|||
{ |
|||
result = typeof(ParseTypeConverter<>).MakeGenericType(type); |
|||
_converters.Add(type, result); |
|||
return result; |
|||
} |
|||
|
|||
_converters.Add(type, null); |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Registers a type converter for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type. Maybe be a non-constructed generic type.</param>
|
|||
/// <param name="converterType">The converter type. Maybe be a non-constructed generic type.</param>
|
|||
public static void Register(Type type, Type converterType) => _converters[type] = converterType; |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Controls; |
|||
using System.ComponentModel; |
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class ClassesTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new Classes(((string)value).Split(' ')); |
|||
} |
|||
} |
|||
} |
|||
@ -1,26 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Media; |
|||
using System.ComponentModel; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
|
|||
|
|||
public class ColorTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Color.Parse((string)value); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class ColumnDefinitionsTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new ColumnDefinitions((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class CornerRadiusTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return CornerRadius.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Input; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class CursorTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
var cursor = (StandardCursorType)Enum.Parse(typeof(StandardCursorType), ((string)value).Trim(), true); |
|||
return new Cursor(cursor); |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class FontFamilyTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return FontFamily.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class GeometryTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return StreamGeometry.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class GridLengthTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return GridLength.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Input; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class KeyGestureConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return KeyGesture.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class MatrixTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Matrix.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
using System.Reflection; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// Base class for type converters which call a static Parse method.
|
|||
/// </summary>
|
|||
public abstract class ParseTypeConverter : TypeConverter |
|||
{ |
|||
protected const BindingFlags PublicStatic = BindingFlags.Public | BindingFlags.Static; |
|||
protected static readonly Type[] StringParameter = new[] { typeof(string) }; |
|||
protected static readonly Type[] StringIFormatProviderParameters = new[] { typeof(string), typeof(IFormatProvider) }; |
|||
|
|||
/// <summary>
|
|||
/// Checks whether a type has a suitable Parse method.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <returns>True if the type has a suitable parse method, otherwise false.</returns>
|
|||
public static bool HasParseMethod(Type type) |
|||
{ |
|||
return type.GetMethod("Parse", PublicStatic, null, StringIFormatProviderParameters, null) != null || |
|||
type.GetMethod("Parse", PublicStatic, null, StringParameter, null) != null; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A type converter which calls a static Parse method.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The type with the Parse method.</typeparam>
|
|||
public class ParseTypeConverter<T> : ParseTypeConverter |
|||
{ |
|||
private static Func<string, T> _parse; |
|||
private static Func<string, IFormatProvider, T> _parseWithFormat; |
|||
|
|||
static ParseTypeConverter() |
|||
{ |
|||
var method = typeof(T).GetMethod("Parse", PublicStatic, null, StringIFormatProviderParameters, null); |
|||
|
|||
if (method != null) |
|||
{ |
|||
_parseWithFormat = (Func<string, IFormatProvider, T>)method |
|||
.CreateDelegate(typeof(Func<string, IFormatProvider, T>)); |
|||
return; |
|||
} |
|||
|
|||
method = typeof(T).GetMethod("Parse", PublicStatic, null, StringParameter, null); |
|||
|
|||
if (method != null) |
|||
{ |
|||
_parse = (Func<string, T>)method.CreateDelegate(typeof(Func<string, T>)); |
|||
} |
|||
} |
|||
|
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
if (value != null) |
|||
{ |
|||
if (_parse != null) |
|||
{ |
|||
return _parse(value.ToString()); |
|||
} |
|||
else if (_parseWithFormat != null) |
|||
{ |
|||
return _parseWithFormat(value.ToString(), culture); |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class PointTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Point.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class RectTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Rect.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class RelativePointTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return RelativePoint.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class RelativeRectTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return RelativeRect.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class RowDefinitionsTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new RowDefinitions((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class SizeTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Size.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System.ComponentModel; |
|||
|
|||
public class ThicknessTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Thickness.Parse((string)value); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue