diff --git a/src/Avalonia.Visuals/Rect.cs b/src/Avalonia.Visuals/Rect.cs
index 0132c5e8a3..d562429fc7 100644
--- a/src/Avalonia.Visuals/Rect.cs
+++ b/src/Avalonia.Visuals/Rect.cs
@@ -481,5 +481,31 @@ namespace Avalonia
_width,
_height);
}
+
+ ///
+ /// Parses a string.
+ ///
+ /// The string.
+ /// The current culture.
+ /// The parsed .
+ public static Rect Parse(string s, CultureInfo culture)
+ {
+ var parts = s.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(x => x.Trim())
+ .ToList();
+
+ if (parts.Count == 4)
+ {
+ return new Rect(
+ double.Parse(parts[0], culture),
+ double.Parse(parts[1], culture),
+ double.Parse(parts[2], culture),
+ double.Parse(parts[3], culture));
+ }
+ else
+ {
+ throw new FormatException("Invalid Rect.");
+ }
+ }
}
}
diff --git a/src/Avalonia.Visuals/RelativeRect.cs b/src/Avalonia.Visuals/RelativeRect.cs
index 3ce3797c49..a11f080e94 100644
--- a/src/Avalonia.Visuals/RelativeRect.cs
+++ b/src/Avalonia.Visuals/RelativeRect.cs
@@ -203,7 +203,7 @@ namespace Avalonia
}
else
{
- throw new FormatException("Invalid Rect.");
+ throw new FormatException("Invalid RelativeRect.");
}
}
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index 84c0f1ef1c..08ea6b6877 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -32,6 +32,7 @@
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/RectTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/RectTypeConverter.cs
new file mode 100644
index 0000000000..c9c6462f89
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/RectTypeConverter.cs
@@ -0,0 +1,23 @@
+// 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, culture);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs
index f8b99f2fdf..1cf5b6a58e 100644
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs
@@ -39,6 +39,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml
{ typeof(RelativeRect), typeof(RelativeRectTypeConverter) },
{ typeof(RowDefinitions), typeof(RowDefinitionsTypeConverter) },
{ typeof(Size), typeof(SizeTypeConverter) },
+ { typeof(Rect), typeof(RectTypeConverter) },
{ typeof(Selector), typeof(SelectorTypeConverter)},
{ typeof(SolidColorBrush), typeof(BrushTypeConverter) },
{ typeof(Thickness), typeof(ThicknessTypeConverter) },
diff --git a/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs
new file mode 100644
index 0000000000..12070bfed3
--- /dev/null
+++ b/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs
@@ -0,0 +1,16 @@
+using System.Globalization;
+using Xunit;
+
+namespace Avalonia.Visuals.UnitTests.Media
+{
+ public class RectTests
+ {
+ [Fact]
+ public void Parse_Parses()
+ {
+ var rect = Rect.Parse("1,2 3,-4", CultureInfo.CurrentCulture);
+ var expected = new Rect(1, 2, 3, -4);
+ Assert.Equal(expected, rect);
+ }
+ }
+}
\ No newline at end of file