Browse Source
- Don't log an error when the target for the root ExpressionNode is null. This is usually because the `DataContext` hasn't been set up yet and it spewed a load of useless error messages. - Add a Description field to `ExpressionObserver` that can be used in the case of e.g. #control bindings to record the whole expression (with the "#control" part) rather than just the part tracked by the `ExpressionObserver`.pull/691/head
14 changed files with 216 additions and 159 deletions
@ -1,15 +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; |
|
||||
|
|
||||
namespace Avalonia.Data |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// An exception returned through <see cref="BindingNotification"/> signalling that a
|
|
||||
/// requested binding expression could not be evaluated.
|
|
||||
/// </summary>
|
|
||||
public class BindingBrokenException : Exception |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,85 @@ |
|||||
|
// 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; |
||||
|
|
||||
|
namespace Avalonia.Data |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// An exception returned through <see cref="BindingNotification"/> signalling that a
|
||||
|
/// requested binding expression could not be evaluated because of a null in one of the links
|
||||
|
/// of the binding chain.
|
||||
|
/// </summary>
|
||||
|
public class BindingChainNullException : Exception |
||||
|
{ |
||||
|
private string _message; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initalizes a new instance of the <see cref="BindingChainNullException"/> class.
|
||||
|
/// </summary>
|
||||
|
public BindingChainNullException() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initalizes a new instance of the <see cref="BindingChainNullException"/> class.
|
||||
|
/// </summary>
|
||||
|
public BindingChainNullException(string message) |
||||
|
{ |
||||
|
_message = message; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initalizes a new instance of the <see cref="BindingChainNullException"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The expression.</param>
|
||||
|
/// <param name="expressionNullPoint">
|
||||
|
/// The point in the expression at which the null was encountered.
|
||||
|
/// </param>
|
||||
|
public BindingChainNullException(string expression, string expressionNullPoint) |
||||
|
{ |
||||
|
Expression = expression; |
||||
|
ExpressionNullPoint = expressionNullPoint; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the expression that could not be evaluated.
|
||||
|
/// </summary>
|
||||
|
public string Expression { get; protected set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the point in the expression at which the null was encountered.
|
||||
|
/// </summary>
|
||||
|
public string ExpressionNullPoint { get; protected set; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override string Message |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_message == null) |
||||
|
{ |
||||
|
_message = BuildMessage(); |
||||
|
} |
||||
|
|
||||
|
return _message; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private string BuildMessage() |
||||
|
{ |
||||
|
if (Expression != null && ExpressionNullPoint != null) |
||||
|
{ |
||||
|
return $"'{ExpressionNullPoint}' is null in expression '{Expression}'."; |
||||
|
} |
||||
|
else if (ExpressionNullPoint != null) |
||||
|
{ |
||||
|
return $"'{ExpressionNullPoint}' is null in expression."; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return "Null encountered in binding expression."; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,65 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Avalonia.Data; |
|
||||
|
|
||||
namespace Avalonia.Markup.Data |
|
||||
{ |
|
||||
public class MarkupBindingBrokenException : BindingBrokenException |
|
||||
{ |
|
||||
private string _message; |
|
||||
|
|
||||
public MarkupBindingBrokenException() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public MarkupBindingBrokenException(string message) |
|
||||
{ |
|
||||
_message = message; |
|
||||
} |
|
||||
|
|
||||
internal MarkupBindingBrokenException(ExpressionNode node) |
|
||||
{ |
|
||||
Nodes.Add(node.Description); |
|
||||
} |
|
||||
|
|
||||
public override string Message |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
if (_message != null) |
|
||||
{ |
|
||||
return _message; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
return _message = BuildMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal string Expression { get; set; } |
|
||||
internal IList<string> Nodes { get; } = new List<string>(); |
|
||||
|
|
||||
private string BuildMessage() |
|
||||
{ |
|
||||
if (Nodes.Count == 0) |
|
||||
{ |
|
||||
return "The binding chain was broken."; |
|
||||
} |
|
||||
else if (Nodes.Count == 1) |
|
||||
{ |
|
||||
return $"'{Nodes[0]}' is null in expression '{Expression}'."; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
var brokenPath = string.Join(".", Nodes.Skip(1).Reverse()) |
|
||||
.Replace(".!", "!") |
|
||||
.Replace(".[", "["); |
|
||||
return $"'{brokenPath}' is null in expression '{Expression}'."; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,33 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Avalonia.Data; |
||||
|
|
||||
|
namespace Avalonia.Markup.Data |
||||
|
{ |
||||
|
internal class MarkupBindingChainNullException : BindingChainNullException |
||||
|
{ |
||||
|
private IList<string> _nodes = new List<string>(); |
||||
|
|
||||
|
public MarkupBindingChainNullException() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public MarkupBindingChainNullException(string expression, string expressionNullPoint) |
||||
|
: base(expression, expressionNullPoint) |
||||
|
{ |
||||
|
_nodes = null; |
||||
|
} |
||||
|
|
||||
|
public bool HasNodes => _nodes.Count > 0; |
||||
|
public void AddNode(string node) => _nodes.Add(node); |
||||
|
|
||||
|
public void Commit(string expression) |
||||
|
{ |
||||
|
Expression = expression; |
||||
|
ExpressionNullPoint = string.Join(".", _nodes.Reverse()) |
||||
|
.Replace(".!", "!") |
||||
|
.Replace(".[", "["); |
||||
|
_nodes = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue