diff --git a/src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs b/src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs index 7df53f430f..15db7a96e4 100644 --- a/src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs +++ b/src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs @@ -88,6 +88,11 @@ namespace Avalonia.Markup.Parsers } else if (ParseOpenBrace(ref r)) { + if (PeekOpenBrace(ref r)) + { + return State.TypeCast; + } + return State.AttachedProperty; } else if (PeekOpenBracket(ref r)) @@ -140,6 +145,11 @@ namespace Avalonia.Markup.Parsers { if (ParseOpenBrace(ref r)) { + if (PeekOpenBrace(ref r)) + { + return State.TypeCast; + } + return State.AttachedProperty; } else @@ -196,23 +206,30 @@ namespace Avalonia.Markup.Parsers private static State ParseTypeCast(ref CharacterReader r, List nodes) { + bool parseMemberBeforeAddCast = ParseOpenBrace(ref r); + var (ns, typeName) = ParseTypeName(ref r); - nodes.Add(new TypeCastNode { Namespace = ns, TypeName = typeName }); + var result = State.AfterMember; - if (ParseMemberAccessor(ref r)) + if (parseMemberBeforeAddCast) { - var identifier = r.ParseIdentifier(); + if (!ParseCloseBrace(ref r)) + { + throw new ExpressionParseException(r.Position, "Expected ')'."); + } - nodes.Add(new PropertyNameNode { PropertyName = identifier.ToString() }); + result = ParseBeforeMember(ref r, nodes); } + nodes.Add(new TypeCastNode { Namespace = ns, TypeName = typeName }); + if (r.End || !r.TakeIf(')')) { throw new ExpressionParseException(r.Position, "Expected ')'."); } - return State.AfterMember; + return result; } private static State ParseElementName(ref CharacterReader r, List nodes) @@ -317,11 +334,21 @@ namespace Avalonia.Markup.Parsers return !r.End && r.TakeIf('('); } + private static bool ParseCloseBrace(ref CharacterReader r) + { + return !r.End && r.TakeIf(')'); + } + private static bool PeekOpenBracket(ref CharacterReader r) { return !r.End && r.Peek == '['; } + private static bool PeekOpenBrace(ref CharacterReader r) + { + return !r.End && r.Peek == '('; + } + private static bool ParseStreamOperator(ref CharacterReader r) { return !r.End && r.TakeIf('^'); @@ -373,9 +400,9 @@ namespace Avalonia.Markup.Parsers } } - public interface INode {} + public interface INode { } - public interface ITransformNode {} + public interface ITransformNode { } public class EmptyExpressionNode : INode { } @@ -396,11 +423,11 @@ namespace Avalonia.Markup.Parsers public IList Arguments { get; set; } } - public class NotNode : INode, ITransformNode {} + public class NotNode : INode, ITransformNode { } - public class StreamNode : INode {} + public class StreamNode : INode { } - public class SelfNode : INode {} + public class SelfNode : INode { } public class NameNode : INode {