diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index bc52e31d2c..63f500270d 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -44,7 +44,7 @@
Properties\SharedAssemblyInfo.cs
-
+
diff --git a/src/Avalonia.Base/Data/BindingChainNullException.cs b/src/Avalonia.Base/Data/BindingChainException.cs
similarity index 52%
rename from src/Avalonia.Base/Data/BindingChainNullException.cs
rename to src/Avalonia.Base/Data/BindingChainException.cs
index 0e50a36d8a..97b0d3ba8b 100644
--- a/src/Avalonia.Base/Data/BindingChainNullException.cs
+++ b/src/Avalonia.Base/Data/BindingChainException.cs
@@ -10,36 +10,39 @@ namespace Avalonia.Data
/// requested binding expression could not be evaluated because of a null in one of the links
/// of the binding chain.
///
- public class BindingChainNullException : Exception
+ public class BindingChainException : Exception
{
private string _message;
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
- public BindingChainNullException()
+ public BindingChainException()
{
}
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
- public BindingChainNullException(string message)
+ /// The error message.
+ public BindingChainException(string message)
{
_message = message;
}
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
+ /// The error message.
/// The expression.
- ///
- /// The point in the expression at which the null was encountered.
+ ///
+ /// The point in the expression at which the error was encountered.
///
- public BindingChainNullException(string expression, string expressionNullPoint)
+ public BindingChainException(string message, string expression, string errorPoint)
{
+ _message = message;
Expression = expression;
- ExpressionNullPoint = expressionNullPoint;
+ ExpressionErrorPoint = errorPoint;
}
///
@@ -48,37 +51,27 @@ namespace Avalonia.Data
public string Expression { get; protected set; }
///
- /// Gets the point in the expression at which the null was encountered.
+ /// Gets the point in the expression at which the error occured.
///
- public string ExpressionNullPoint { get; protected set; }
+ public string ExpressionErrorPoint { get; protected set; }
///
public override string Message
{
get
{
- if (_message == null)
+ if (Expression != null && ExpressionErrorPoint != null)
{
- _message = BuildMessage();
+ return $"{_message} in expression '{Expression}' at '{ExpressionErrorPoint}'.";
+ }
+ else if (ExpressionErrorPoint != null)
+ {
+ return $"{_message} in expression '{ExpressionErrorPoint}'.";
+ }
+ else
+ {
+ return $"{_message} in expression.";
}
-
- 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.";
}
}
}
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index cd3dd0d098..ea4d6b1f22 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -547,7 +547,7 @@ namespace Avalonia.Controls
var exceptions = aggregate == null ?
(IEnumerable)new[] { exception } :
aggregate.InnerExceptions;
- var filtered = exceptions.Where(x => !(x is BindingChainNullException)).ToList();
+ var filtered = exceptions.Where(x => !(x is BindingChainException)).ToList();
if (filtered.Count > 0)
{
diff --git a/src/Avalonia.Input/AccessKeyHandler.cs b/src/Avalonia.Input/AccessKeyHandler.cs
index 7acbc109fc..7baa4103d7 100644
--- a/src/Avalonia.Input/AccessKeyHandler.cs
+++ b/src/Avalonia.Input/AccessKeyHandler.cs
@@ -43,6 +43,16 @@ namespace Avalonia.Input
///
private bool _ignoreAltUp;
+ ///
+ /// Whether the AltKey is down.
+ ///
+ private bool _altIsDown;
+
+ ///
+ /// Element to restore folowing AltKey taking focus.
+ ///
+ private IInputElement _restoreFocusElement;
+
///
/// Gets or sets the window's main menu.
///
@@ -110,8 +120,14 @@ namespace Avalonia.Input
{
if (e.Key == Key.LeftAlt)
{
+ _altIsDown = true;
+
if (MainMenu == null || !MainMenu.IsOpen)
{
+ // TODO: Use FocusScopes to store the current element and restore it when context menu is closed.
+ // Save currently focused input element.
+ _restoreFocusElement = FocusManager.Instance.Current;
+
// When Alt is pressed without a main menu, or with a closed main menu, show
// access key markers in the window (i.e. "_File").
_owner.ShowAccessKeys = _showingAccessKeys = true;
@@ -121,11 +137,18 @@ namespace Avalonia.Input
// If the Alt key is pressed and the main menu is open, close the main menu.
CloseMenu();
_ignoreAltUp = true;
+
+ _restoreFocusElement?.Focus();
+ _restoreFocusElement = null;
}
// We always handle the Alt key.
e.Handled = true;
}
+ else if (_altIsDown)
+ {
+ _ignoreAltUp = true;
+ }
}
///
@@ -179,6 +202,8 @@ namespace Avalonia.Input
switch (e.Key)
{
case Key.LeftAlt:
+ _altIsDown = false;
+
if (_ignoreAltUp)
{
_ignoreAltUp = false;
diff --git a/src/Markup/Avalonia.Markup.Xaml/OmniXAML b/src/Markup/Avalonia.Markup.Xaml/OmniXAML
index b122549406..544af79d21 160000
--- a/src/Markup/Avalonia.Markup.Xaml/OmniXAML
+++ b/src/Markup/Avalonia.Markup.Xaml/OmniXAML
@@ -1 +1 @@
-Subproject commit b122549406107170bbe6e67c0d6a1a4252beef77
+Subproject commit 544af79d218127b4174da4be19896c5ca78eaa5d
diff --git a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
index 88c4a6ab18..1c3f453280 100644
--- a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
+++ b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
@@ -42,7 +42,8 @@
Properties\SharedAssemblyInfo.cs
-
+
+
@@ -63,9 +64,9 @@
-
-
-
+
+
+
diff --git a/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs b/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
index b0957c7187..93f20e4c77 100644
--- a/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
+++ b/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
@@ -17,7 +17,6 @@ namespace Avalonia.Markup.Data
private WeakReference _target = UnsetReference;
private IDisposable _valueSubscription;
private IObserver