Browse Source

Merge branch 'master' of https://github.com/AvaloniaUI/Avalonia into wip-animations

pull/1461/head
Jumar Macato 8 years ago
parent
commit
ca3b8b259f
  1. 18
      src/Avalonia.Base/Collections/AvaloniaListConverter.cs
  2. 7
      src/Avalonia.Controls/Classes.cs
  3. 8
      src/Avalonia.Controls/ColumnDefinitions.cs
  4. 8
      src/Avalonia.Controls/RowDefinitions.cs
  5. 7
      src/Avalonia.Input/Cursors.cs
  6. 4
      src/Avalonia.Visuals/Media/Brush.cs
  7. 13
      src/Avalonia.Visuals/Media/BrushConverter.cs
  8. 7
      src/Avalonia.Visuals/Media/Geometry.cs
  9. 3
      src/Avalonia.Visuals/Media/IBrush.cs
  10. 15
      src/Avalonia.Visuals/Media/SolidColorBrush.cs
  11. 2
      src/Avalonia.Visuals/Media/StreamGeometry.cs
  12. 26
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  13. 84
      src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs
  14. 22
      src/Markup/Avalonia.Markup.Xaml/Converters/ClassesTypeConverter.cs
  15. 26
      src/Markup/Avalonia.Markup.Xaml/Converters/ColorTypeConverter.cs
  16. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs
  17. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/CornerRadiusTypeConverter.cs
  18. 25
      src/Markup/Avalonia.Markup.Xaml/Converters/CursorTypeConverter.cs
  19. 20
      src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
  20. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/GeometryTypeConverter.cs
  21. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/GridLengthTypeConverter.cs
  22. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/KeyGestureConverter.cs
  23. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/MatrixTypeConverter.cs
  24. 5
      src/Markup/Avalonia.Markup.Xaml/Converters/MemberSelectorTypeConverter.cs
  25. 79
      src/Markup/Avalonia.Markup.Xaml/Converters/ParseTypeConverter.cs
  26. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/PointTypeConverter.cs
  27. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/RectTypeConverter.cs
  28. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/RelativePointTypeConverter.cs
  29. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/RelativeRectTypeConverter.cs
  30. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs
  31. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/SizeTypeConverter.cs
  32. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/ThicknessTypeConverter.cs
  33. 2
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaTypeAttributeProvider.cs
  34. 5
      src/Markup/Avalonia.Markup.Xaml/Templates/MemberSelector.cs
  35. 1
      tests/Avalonia.Base.UnitTests/Collections/AvaloniaListTests.cs
  36. 2
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
  37. 4
      tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs

18
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaListTypeConverter.cs → src/Avalonia.Base/Collections/AvaloniaListConverter.cs

@ -2,16 +2,16 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.ComponentModel;
using System.Globalization;
using Avalonia.Collections;
using Avalonia.Utilities;
namespace Avalonia.Markup.Xaml.Converters
namespace Avalonia.Collections
{
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class AvaloniaListTypeConverter<T> : TypeConverter
/// <summary>
/// Creates an <see cref="AvaloniaList{T}"/> from a string representation.
/// </summary>
public class AvaloniaListConverter<T> : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
@ -21,13 +21,13 @@ namespace Avalonia.Markup.Xaml.Converters
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var result = new AvaloniaList<T>();
// TODO: Use StringTokenizer here.
var values = ((string)value).Split(',');
foreach (var s in values)
{
object v;
if (TypeUtilities.TryConvert(typeof(T), s, culture, out v))
if (TypeUtilities.TryConvert(typeof(T), s, culture, out var v))
{
result.Add((T)v);
}

7
src/Avalonia.Controls/Classes.cs

@ -41,6 +41,13 @@ namespace Avalonia.Controls
{
}
/// <summary>
/// Parses a classes string.
/// </summary>
/// <param name="s">The string.</param>
/// <returns>The <see cref="Classes"/>.</returns>
public static Classes Parse(string s) => new Classes(s.Split(' '));
/// <summary>
/// Adds a style class to the collection.
/// </summary>

8
src/Avalonia.Controls/ColumnDefinitions.cs

@ -1,7 +1,6 @@
// 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.Globalization;
using System.Linq;
using Avalonia.Collections;
@ -29,5 +28,12 @@ namespace Avalonia.Controls
{
AddRange(GridLength.ParseLengths(s).Select(x => new ColumnDefinition(x)));
}
/// <summary>
/// Parses a string representation of column definitions collection.
/// </summary>
/// <param name="s">The column definitions string.</param>
/// <returns>The <see cref="ColumnDefinitions"/>.</returns>
public static ColumnDefinitions Parse(string s) => new ColumnDefinitions(s);
}
}

8
src/Avalonia.Controls/RowDefinitions.cs

@ -1,7 +1,6 @@
// 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.Globalization;
using System.Linq;
using Avalonia.Collections;
@ -29,5 +28,12 @@ namespace Avalonia.Controls
{
AddRange(GridLength.ParseLengths(s).Select(x => new RowDefinition(x)));
}
/// <summary>
/// Parses a string representation of row definitions collection.
/// </summary>
/// <param name="s">The row definitions string.</param>
/// <returns>The <see cref="RowDefinitions"/>.</returns>
public static RowDefinitions Parse(string s) => new RowDefinitions(s);
}
}

7
src/Avalonia.Input/Cursors.cs

@ -65,6 +65,13 @@ namespace Avalonia.Input
public IPlatformHandle PlatformCursor { get; }
public static Cursor Parse(string s)
{
return Enum.TryParse<StandardCursorType>(s, true, out var t) ?
new Cursor(t) :
throw new ArgumentException($"Unrecognised cursor type '{s}'.");
}
private static IPlatformHandle GetCursor(StandardCursorType type)
{
var platform = AvaloniaLocator.Current.GetService<IStandardCursorFactory>();

4
src/Avalonia.Visuals/Media/Brush.cs

@ -2,14 +2,14 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reflection;
using System.ComponentModel;
namespace Avalonia.Media
{
/// <summary>
/// Describes how an area is painted.
/// </summary>
[TypeConverter(typeof(BrushConverter))]
public abstract class Brush : AvaloniaObject, IBrush
{
/// <summary>

13
src/Markup/Avalonia.Markup.Xaml/Converters/BrushTypeConverter.cs → src/Avalonia.Visuals/Media/BrushConverter.cs

@ -2,16 +2,15 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.ComponentModel;
using System.Globalization;
using Avalonia.Media;
namespace Avalonia.Markup.Xaml.Converters
namespace Avalonia.Media
{
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class BrushTypeConverter : TypeConverter
/// <summary>
/// Creates an <see cref="IBrush"/> from a string representation.
/// </summary>
public class BrushConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{

7
src/Avalonia.Visuals/Media/Geometry.cs

@ -69,6 +69,13 @@ namespace Avalonia.Media
set { SetValue(TransformProperty, value); }
}
/// <summary>
/// Creates a <see cref="Geometry"/> from a string.
/// </summary>
/// <param name="s">The string.</param>
/// <returns>A <see cref="StreamGeometry"/>.</returns>
public static Geometry Parse(string s) => StreamGeometry.Parse(s);
/// <summary>
/// Clones the geometry.
/// </summary>

3
src/Avalonia.Visuals/Media/IBrush.cs

@ -1,11 +1,14 @@
// 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.ComponentModel;
namespace Avalonia.Media
{
/// <summary>
/// Describes how an area is painted.
/// </summary>
[TypeConverter(typeof(BrushConverter))]
public interface IBrush
{
/// <summary>

15
src/Avalonia.Visuals/Media/SolidColorBrush.cs

@ -52,6 +52,21 @@ namespace Avalonia.Media
set { SetValue(ColorProperty, value); }
}
/// <summary>
/// Parses a brush string.
/// </summary>
/// <param name="s">The brush string.</param>
/// <returns>The <see cref="Color"/>.</returns>
/// <remarks>
/// Whereas <see cref="Brush.Parse(string)"/> may return an immutable solid color brush,
/// this method always returns a mutable <see cref="SolidColorBrush"/>.
/// </remarks>
public static new SolidColorBrush Parse(string s)
{
var brush = (ISolidColorBrush)Brush.Parse(s);
return brush is SolidColorBrush solid ? solid : new SolidColorBrush(brush.Color);
}
/// <summary>
/// Returns a string representation of the brush.
/// </summary>

2
src/Avalonia.Visuals/Media/StreamGeometry.cs

@ -33,7 +33,7 @@ namespace Avalonia.Media
/// </summary>
/// <param name="s">The string.</param>
/// <returns>A <see cref="StreamGeometry"/>.</returns>
public static StreamGeometry Parse(string s)
public static new StreamGeometry Parse(string s)
{
StreamGeometry result = new StreamGeometry();

26
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -26,11 +26,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="AvaloniaXamlLoader.cs" />
<Compile Include="Converters\CornerRadiusTypeConverter.cs" />
<Compile Include="Converters\FontFamilyTypeConverter.cs" />
<Compile Include="Converters\MatrixTypeConverter.cs" />
<Compile Include="Converters\RectTypeConverter.cs" />
<Compile Include="Converters\MemberSelectorTypeConverter.cs" />
<Compile Include="Converters\ParseTypeConverter.cs" />
<Compile Include="Converters\SetterValueTypeConverter.cs" />
<Compile Include="Converters\TimeSpanTypeConverter.cs" />
<Compile Include="Data\ResourceInclude.cs" />
<Compile Include="MarkupExtensions\DynamicResourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticResourceExtension.cs" />
@ -39,32 +38,15 @@
<Compile Include="PortableXaml\AttributeExtensions.cs" />
<Compile Include="PortableXaml\AvaloniaMemberAttributeProvider.cs" />
<Compile Include="PortableXaml\AvaloniaNameScope.cs" />
<Compile Include="PortableXaml\AvaloniaDefaultTypeConverters.cs" />
<Compile Include="AvaloniaTypeConverters.cs" />
<Compile Include="PortableXaml\AvaloniaXamlObjectWriter.cs" />
<Compile Include="PortableXaml\AvaloniaRuntimeTypeProvider.cs" />
<Compile Include="PortableXaml\AvaloniaXamlSchemaContext.cs" />
<Compile Include="Converters\BitmapTypeConverter.cs" />
<Compile Include="Converters\BrushTypeConverter.cs" />
<Compile Include="Converters\ClassesTypeConverter.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
<Compile Include="Converters\CursorTypeConverter.cs" />
<Compile Include="Converters\GeometryTypeConverter.cs" />
<Compile Include="Converters\GridLengthTypeConverter.cs" />
<Compile Include="Converters\IconTypeConverter.cs" />
<Compile Include="Converters\KeyGestureConverter.cs" />
<Compile Include="Converters\MemberSelectorTypeConverter.cs" />
<Compile Include="Converters\AvaloniaListTypeConverter.cs" />
<Compile Include="Converters\AvaloniaPropertyTypeConverter.cs" />
<Compile Include="Converters\PointsListTypeConverter.cs" />
<Compile Include="Converters\SizeTypeConverter.cs" />
<Compile Include="Converters\PointTypeConverter.cs" />
<Compile Include="Converters\RelativePointTypeConverter.cs" />
<Compile Include="Converters\RelativeRectTypeConverter.cs" />
<Compile Include="Converters\RowDefinitionsTypeConverter.cs" />
<Compile Include="Converters\SelectorTypeConverter.cs" />
<Compile Include="Converters\ThicknessTypeConverter.cs" />
<Compile Include="Converters\TimeSpanTypeConverter.cs" />
<Compile Include="Data\Binding.cs" />
<Compile Include="Data\DelayedBinding.cs" />
<Compile Include="Data\MultiBinding.cs" />

84
src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs

@ -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;
}
}

22
src/Markup/Avalonia.Markup.Xaml/Converters/ClassesTypeConverter.cs

@ -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(' '));
}
}
}

26
src/Markup/Avalonia.Markup.Xaml/Converters/ColorTypeConverter.cs

@ -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);
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs

@ -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);
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/CornerRadiusTypeConverter.cs

@ -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);
}
}
}

25
src/Markup/Avalonia.Markup.Xaml/Converters/CursorTypeConverter.cs

@ -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);
}
}
}

20
src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs

@ -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);
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/GeometryTypeConverter.cs

@ -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);
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/GridLengthTypeConverter.cs

@ -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);
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/KeyGestureConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/MatrixTypeConverter.cs

@ -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);
}
}
}

5
src/Markup/Avalonia.Markup.Xaml/Converters/MemberSelectorTypeConverter.cs

@ -18,10 +18,7 @@ namespace Avalonia.Markup.Xaml.Converters
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new MemberSelector
{
MemberName = (string)value,
};
return MemberSelector.Parse((string)value);
}
}
}

79
src/Markup/Avalonia.Markup.Xaml/Converters/ParseTypeConverter.cs

@ -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;
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/PointTypeConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/RectTypeConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/RelativePointTypeConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/RelativeRectTypeConverter.cs

@ -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);
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/SizeTypeConverter.cs

@ -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);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/ThicknessTypeConverter.cs

@ -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);
}
}
}

2
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaTypeAttributeProvider.cs

@ -46,7 +46,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml
if (result == null)
{
var convType = AvaloniaDefaultTypeConverters.GetTypeConverter(_type);
var convType = AvaloniaTypeConverters.GetTypeConverter(_type);
if (convType != null)
{

5
src/Markup/Avalonia.Markup.Xaml/Templates/MemberSelector.cs

@ -25,6 +25,11 @@ namespace Avalonia.Markup.Xaml.Templates
}
}
public static MemberSelector Parse(string s)
{
return new MemberSelector { MemberName = s };
}
public object Select(object o)
{
if (string.IsNullOrEmpty(MemberName))

1
tests/Avalonia.Base.UnitTests/Collections/AvaloniaListTests.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using Avalonia.Collections;
using Xunit;

2
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@ -530,7 +530,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
style.TryGetResource("Brush", out var brush);
Assert.NotNull(brush);
Assert.IsType<SolidColorBrush>(brush);
Assert.Equal(Colors.White, ((ISolidColorBrush)brush).Color);
style.TryGetResource("Double", out var d);

4
tests/Avalonia.Visuals.UnitTests/Media/Fonts/FontFamilyLoaderTests.cs

@ -11,7 +11,7 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts
{
using System.Diagnostics;
public class FontFamilyLoaderTests
public class FontFamilyLoaderTests : IDisposable
{
private const string FontName = "#MyFont";
private const string Assembly = "?assembly=Avalonia.Visuals.UnitTests";
@ -35,7 +35,7 @@ namespace Avalonia.Visuals.UnitTests.Media.Fonts
_testApplication = StartWithResources(fontAssets);
}
~FontFamilyLoaderTests()
public void Dispose()
{
_testApplication.Dispose();
}

Loading…
Cancel
Save