Browse Source

Fix a few issues with AvaloniaPropertyTypeConverter

- Don't use regex to parse property strings, use `PropertyParser`
- Handle XAML namespaces on attached properties

Fixes #1764
pull/1773/head
Steven Kirk 8 years ago
parent
commit
0b796adc53
  1. 37
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

37
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

@ -4,19 +4,16 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization; using System.Globalization;
using System.Text.RegularExpressions; using Avalonia.Markup.Parsers;
using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Markup.Xaml.Templates; using Avalonia.Markup.Xaml.Templates;
using Avalonia.Styling; using Avalonia.Styling;
using Portable.Xaml;
using Portable.Xaml.ComponentModel; using Portable.Xaml.ComponentModel;
using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.Converters namespace Avalonia.Markup.Xaml.Converters
{ {
public class AvaloniaPropertyTypeConverter : TypeConverter public class AvaloniaPropertyTypeConverter : TypeConverter
{ {
private static readonly Regex regex = new Regex(@"^\(?(\w*)\.(\w*)\)?|(.*)$");
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{ {
return sourceType == typeof(string); return sourceType == typeof(string);
@ -24,8 +21,10 @@ namespace Avalonia.Markup.Xaml.Converters
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{ {
var (owner, propertyName) = ParseProperty((string)value); var parser = new PropertyParser();
var ownerType = TryResolveOwnerByName(context, owner) ?? var reader = new Reader((string)value);
var (ns, owner, propertyName) = parser.Parse(reader);
var ownerType = TryResolveOwnerByName(context, ns, owner) ??
context.GetFirstAmbientValue<ControlTemplate>()?.TargetType ?? context.GetFirstAmbientValue<ControlTemplate>()?.TargetType ??
context.GetFirstAmbientValue<Style>()?.Selector?.TargetType; context.GetFirstAmbientValue<Style>()?.Selector?.TargetType;
@ -47,16 +46,16 @@ namespace Avalonia.Markup.Xaml.Converters
return property; return property;
} }
private Type TryResolveOwnerByName(ITypeDescriptorContext context, string owner) private Type TryResolveOwnerByName(ITypeDescriptorContext context, string ns, string owner)
{ {
if (owner != null) if (owner != null)
{ {
var resolver = context.GetService<IXamlTypeResolver>(); var result = context.ResolveType(ns, owner);
var result = resolver.Resolve(owner);
if (result == null) if (result == null)
{ {
throw new XamlLoadException($"Could not find type '{owner}'."); var name = string.IsNullOrEmpty(ns) ? owner : $"{ns}:{owner}";
throw new XamlLoadException($"Could not find type '{name}'.");
} }
return result; return result;
@ -64,19 +63,5 @@ namespace Avalonia.Markup.Xaml.Converters
return null; return null;
} }
private (string owner, string property) ParseProperty(string s)
{
var result = regex.Match(s);
if (result.Groups[1].Success)
{
return (result.Groups[1].Value, result.Groups[2].Value);
}
else
{
return (null, result.Groups[3].Value);
}
}
} }
} }

Loading…
Cancel
Save