diff --git a/Perspex.Controls/Control.cs b/Perspex.Controls/Control.cs
index 7cc3545838..8b98f0fd7e 100644
--- a/Perspex.Controls/Control.cs
+++ b/Perspex.Controls/Control.cs
@@ -355,7 +355,7 @@ namespace Perspex.Controls
{
base.OnGotFocus(e);
- if (this.IsFocused && e.KeyboardNavigated)
+ if (this.IsFocused && e.NavigationMethod == NavigationMethod.Tab)
{
var adornerLayer = AdornerLayer.GetAdornerLayer(this);
diff --git a/Perspex.Controls/Primitives/SelectingItemsControl.cs b/Perspex.Controls/Primitives/SelectingItemsControl.cs
index b73e13947f..c1c9bf7454 100644
--- a/Perspex.Controls/Primitives/SelectingItemsControl.cs
+++ b/Perspex.Controls/Primitives/SelectingItemsControl.cs
@@ -159,7 +159,19 @@ namespace Perspex.Controls.Primitives
protected override void OnGotFocus(GotFocusEventArgs e)
{
base.OnGotFocus(e);
- this.TrySetSelectionFromContainerEvent(e.Source, true);
+
+ if (e.NavigationMethod == NavigationMethod.Pointer ||
+ e.NavigationMethod == NavigationMethod.Directional)
+ {
+ this.TrySetSelectionFromContainerEvent(e.Source, true);
+ }
+ }
+
+ ///
+ protected override void OnPointerPressed(PointerPressEventArgs e)
+ {
+ base.OnPointerPressed(e);
+ e.Handled = true;
}
///
diff --git a/Perspex.Input/FocusManager.cs b/Perspex.Input/FocusManager.cs
index 2be4f28ebc..1baa6b022f 100644
--- a/Perspex.Input/FocusManager.cs
+++ b/Perspex.Input/FocusManager.cs
@@ -65,10 +65,8 @@ namespace Perspex.Input
/// Focuses a control.
///
/// The control to focus.
- ///
- /// Whether the control was focused by a keypress (e.g. the Tab key).
- ///
- public void Focus(IInputElement control, bool keyboardNavigated = false)
+ /// The method by which focus was changed.
+ public void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified)
{
if (control != null)
{
@@ -78,7 +76,7 @@ namespace Perspex.Input
if (scope != null)
{
this.Scope = scope;
- this.SetFocusedElement(scope, control, keyboardNavigated);
+ this.SetFocusedElement(scope, control, method);
}
}
else if (this.Current != null)
@@ -90,7 +88,7 @@ namespace Perspex.Input
if (this.focusScopes.TryGetValue(scope, out element))
{
- this.Focus(element, keyboardNavigated);
+ this.Focus(element, method);
break;
}
}
@@ -102,9 +100,7 @@ namespace Perspex.Input
///
/// The focus scope.
/// The element to focus. May be null.
- ///
- /// Whether the control was focused by a keypress (e.g. the Tab key).
- ///
+ /// The method by which focus was changed.
///
/// If the specified scope is the current then the keyboard focus
/// will change.
@@ -112,7 +108,7 @@ namespace Perspex.Input
public void SetFocusedElement(
IFocusScope scope,
IInputElement element,
- bool keyboardNavigated = false)
+ NavigationMethod method = NavigationMethod.Unspecified)
{
Contract.Requires(scope != null);
@@ -120,7 +116,7 @@ namespace Perspex.Input
if (this.Scope == scope)
{
- KeyboardDevice.Instance.SetFocusedElement(element, keyboardNavigated);
+ KeyboardDevice.Instance.SetFocusedElement(element, method);
}
}
@@ -196,7 +192,7 @@ namespace Perspex.Input
if (element != null)
{
- this.Focus(element);
+ this.Focus(element, NavigationMethod.Pointer);
}
}
}
diff --git a/Perspex.Input/GotFocusEventArgs.cs b/Perspex.Input/GotFocusEventArgs.cs
index bf393ed4d1..cf7cd12bde 100644
--- a/Perspex.Input/GotFocusEventArgs.cs
+++ b/Perspex.Input/GotFocusEventArgs.cs
@@ -8,12 +8,14 @@ namespace Perspex.Input
{
using Perspex.Interactivity;
+ ///
+ /// Holds arguments for a .
+ ///
public class GotFocusEventArgs : RoutedEventArgs
{
///
- /// Gets or sets a value indicating whether the control was focused by a keypress (e.g.
- /// the Tab key).
+ /// Gets or sets a value indicating how the change in focus occurred.
///
- public bool KeyboardNavigated { get; set; }
+ public NavigationMethod NavigationMethod { get; set; }
}
}
diff --git a/Perspex.Input/IFocusManager.cs b/Perspex.Input/IFocusManager.cs
index 8b67ad19c4..3a82a2abca 100644
--- a/Perspex.Input/IFocusManager.cs
+++ b/Perspex.Input/IFocusManager.cs
@@ -22,10 +22,8 @@ namespace Perspex.Input
/// Focuses a control.
///
/// The control to focus.
- ///
- /// Whether the control was focused by a keypress (e.g. the Tab key).
- ///
- void Focus(IInputElement focusable, bool keyboardNavigated = false);
+ /// The method by which focus was changed.
+ void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified);
///
/// Notifies the focus manager of a change in focus scope.
diff --git a/Perspex.Input/IKeyboardDevice.cs b/Perspex.Input/IKeyboardDevice.cs
index a43fb0cd2a..71bed251a9 100644
--- a/Perspex.Input/IKeyboardDevice.cs
+++ b/Perspex.Input/IKeyboardDevice.cs
@@ -32,6 +32,6 @@ namespace Perspex.Input
ModifierKeys Modifiers { get; }
- void SetFocusedElement(IInputElement element, bool keyboardNavigated);
+ void SetFocusedElement(IInputElement element, NavigationMethod method);
}
}
diff --git a/Perspex.Input/InputElement.cs b/Perspex.Input/InputElement.cs
index b80e3f24a1..bc83f47607 100644
--- a/Perspex.Input/InputElement.cs
+++ b/Perspex.Input/InputElement.cs
@@ -228,7 +228,7 @@ namespace Perspex.Input
protected virtual void OnGotFocus(GotFocusEventArgs e)
{
this.IsFocused = e.OriginalSource == this;
- this.SetValue(IsTabFocusedProperty, e.KeyboardNavigated);
+ this.SetValue(IsTabFocusedProperty, e.NavigationMethod == NavigationMethod.Tab);
}
protected virtual void OnLostFocus(RoutedEventArgs e)
diff --git a/Perspex.Input/KeyboardDevice.cs b/Perspex.Input/KeyboardDevice.cs
index 6758cbbd0b..3dfc451171 100644
--- a/Perspex.Input/KeyboardDevice.cs
+++ b/Perspex.Input/KeyboardDevice.cs
@@ -60,7 +60,7 @@ namespace Perspex.Input
public abstract ModifierKeys Modifiers { get; }
- public void SetFocusedElement(IInputElement element, bool keyboardNavigated)
+ public void SetFocusedElement(IInputElement element, NavigationMethod method)
{
if (element != this.FocusedElement)
{
@@ -82,7 +82,7 @@ namespace Perspex.Input
interactive.RaiseEvent(new GotFocusEventArgs
{
RoutedEvent = InputElement.GotFocusEvent,
- KeyboardNavigated = keyboardNavigated,
+ NavigationMethod = method,
});
}
}
diff --git a/Perspex.Input/KeyboardNavigationHandler.cs b/Perspex.Input/KeyboardNavigationHandler.cs
index 196cdab107..175a9ee4ed 100644
--- a/Perspex.Input/KeyboardNavigationHandler.cs
+++ b/Perspex.Input/KeyboardNavigationHandler.cs
@@ -78,7 +78,10 @@ namespace Perspex.Input
if (next != null)
{
- FocusManager.Instance.Focus(next, true);
+ var method = direction == FocusNavigationDirection.Next ||
+ direction == FocusNavigationDirection.Previous ?
+ NavigationMethod.Tab : NavigationMethod.Directional;
+ FocusManager.Instance.Focus(next, method);
}
}
diff --git a/Perspex.Input/NavigationMethod.cs b/Perspex.Input/NavigationMethod.cs
new file mode 100644
index 0000000000..a4c2d75c83
--- /dev/null
+++ b/Perspex.Input/NavigationMethod.cs
@@ -0,0 +1,35 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Input
+{
+ ///
+ /// Defines the method by which a focus change occurred.
+ ///
+ public enum NavigationMethod
+ {
+ ///
+ /// The focus was changed by an unspecified method, e.g. calling
+ /// .
+ ///
+ Unspecified,
+
+ ///
+ /// The focus was changed by the user tabbing between control.
+ ///
+ Tab,
+
+ ///
+ /// The focus was changed by the user pressing a directional navigation key.
+ ///
+ Directional,
+
+ ///
+ /// The focus was changed by a pointer click.
+ ///
+ Pointer,
+ }
+}
diff --git a/Perspex.Input/Perspex.Input.csproj b/Perspex.Input/Perspex.Input.csproj
index bb20879f6b..aab6e3a5e3 100644
--- a/Perspex.Input/Perspex.Input.csproj
+++ b/Perspex.Input/Perspex.Input.csproj
@@ -61,6 +61,7 @@
+
diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs
index 26fc19e3cf..c58618bf60 100644
--- a/TestApplication/Program.cs
+++ b/TestApplication/Program.cs
@@ -492,7 +492,6 @@ namespace TestApplication
(listBox = new ListBox
{
Items = listBoxData,
- SelectedIndex = 0,
MaxHeight = 300,
}),
new DropDown
diff --git a/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
index f45cf4f664..d0ac23e29a 100644
--- a/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
+++ b/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
@@ -334,7 +334,7 @@ namespace Perspex.Controls.UnitTests.Primitives
}
[Fact]
- public void Focusing_Item_Should_Select_It()
+ public void Focusing_Item_With_Pointer_Should_Select_It()
{
var target = new SelectingItemsControl
{
@@ -346,7 +346,33 @@ namespace Perspex.Controls.UnitTests.Primitives
var e = new GotFocusEventArgs
{
- RoutedEvent = InputElement.GotFocusEvent
+ RoutedEvent = InputElement.GotFocusEvent,
+ NavigationMethod = NavigationMethod.Pointer,
+ };
+
+ target.Presenter.Panel.Children[1].RaiseEvent(e);
+
+ Assert.Equal(1, target.SelectedIndex);
+
+ // GotFocus should be raised on parent control.
+ Assert.False(e.Handled);
+ }
+
+ [Fact]
+ public void Focusing_Item_With_Directional_Keys_Should_Select_It()
+ {
+ var target = new SelectingItemsControl
+ {
+ Template = this.Template(),
+ Items = new[] { "foo", "bar" },
+ };
+
+ target.ApplyTemplate();
+
+ var e = new GotFocusEventArgs
+ {
+ RoutedEvent = InputElement.GotFocusEvent,
+ NavigationMethod = NavigationMethod.Directional,
};
target.Presenter.Panel.Children[1].RaiseEvent(e);
@@ -355,6 +381,28 @@ namespace Perspex.Controls.UnitTests.Primitives
Assert.False(e.Handled);
}
+ [Fact]
+ public void Focusing_Item_With_Tab_Should_Not_Select_It()
+ {
+ var target = new SelectingItemsControl
+ {
+ Template = this.Template(),
+ Items = new[] { "foo", "bar" },
+ };
+
+ target.ApplyTemplate();
+
+ var e = new GotFocusEventArgs
+ {
+ RoutedEvent = InputElement.GotFocusEvent,
+ NavigationMethod = NavigationMethod.Tab,
+ };
+
+ target.Presenter.Panel.Children[1].RaiseEvent(e);
+
+ Assert.Equal(-1, target.SelectedIndex);
+ }
+
[Fact]
public void Raising_IsSelectedChanged_On_Item_Should_Update_Selection()
{
diff --git a/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs b/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs
index c2162f035a..ab01df1f05 100644
--- a/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs
+++ b/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs
@@ -54,7 +54,7 @@ namespace Perspex.Win32.Input
public void WindowActivated(Window window)
{
- this.SetFocusedElement(window, false);
+ this.SetFocusedElement(window, NavigationMethod.Unspecified);
}
public string StringFromVirtualKey(uint virtualKey)