Skip to content

Instantly share code, notes, and snippets.

@dbeattie71
Created November 1, 2012 22:31
Show Gist options
  • Save dbeattie71/3997130 to your computer and use it in GitHub Desktop.
Save dbeattie71/3997130 to your computer and use it in GitHub Desktop.
KeyboardTabBehavior to work with Telerik TextBox and PasswordBox
public class KeyboardTabBehavior : Behavior<UIElement>
{
private KeyboardTabHelper _keyboardTabHelper;
protected override void OnAttached()
{
base.OnAttached();
_keyboardTabHelper = new KeyboardTabHelper(AssociatedObject);
}
protected override void OnDetaching()
{
base.OnDetaching();
_keyboardTabHelper.OnDetach();
}
}
public class KeyboardTabHelper
{
private readonly UIElement _associatedObject;
private readonly PhoneApplicationPage _phoneApplicationPage;
private List<TabControl> _tabControls;
private TabControl _lastTabControl;
public KeyboardTabHelper(UIElement associatedObject)
{
_associatedObject = associatedObject;
_phoneApplicationPage =
((PhoneApplicationFrame) Application.Current.RootVisual).Content as PhoneApplicationPage;
if (_phoneApplicationPage == null)
throw new NullReferenceException("_phoneApplicationPage");
_phoneApplicationPage.Loaded += OnPhoneApplicationPageOnLoaded;
_associatedObject.KeyDown += OnAssociatedObjectKeyDown;
}
public void OnDetach()
{
UnRegisterTabControlEvents(_tabControls);
_associatedObject.KeyDown -= OnAssociatedObjectKeyDown;
_phoneApplicationPage.Loaded -= OnPhoneApplicationPageOnLoaded;
}
private void OnPhoneApplicationPageOnLoaded(object sender, RoutedEventArgs args)
{
FindTabControls((UIElement) sender);
}
private void FindTabControls(UIElement layoutRoot)
{
_tabControls = GetChildren(layoutRoot).OfType<Control>()
.Where(c => c.IsTabStop && c.TabIndex != int.MaxValue)
.OrderBy(c => c.TabIndex)
.Select(c => new TabControl {Control = c, KeyboardFocusedControl = null})
.ToList();
RegisterTabControlEvents(_tabControls);
if (_tabControls.Count > 0)
_lastTabControl = _tabControls[_tabControls.Count - 1];
}
private void RegisterTabControlEvents(IEnumerable<TabControl> tabControls)
{
tabControls.Apply(tabControl => { tabControl.Control.GotFocus += OnTabbedControlGotFocus; });
}
private void UnRegisterTabControlEvents(IEnumerable<TabControl> tabbedControls)
{
tabbedControls.Apply(tabControl => { tabControl.Control.GotFocus -= OnTabbedControlGotFocus; });
}
private void OnTabbedControlGotFocus(object sender, RoutedEventArgs e)
{
var tabControlWithFocus = _tabControls.FirstOrDefault(t => t.Control == sender);
if (tabControlWithFocus == null)
return;
tabControlWithFocus.KeyboardFocusedControl = e.OriginalSource as Control;
}
private void OnAssociatedObjectKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
HandleReturnKey();
}
private void HandleReturnKey()
{
var controlWithFocus = FocusManager.GetFocusedElement() as Control;
if (controlWithFocus == null)
return;
var tabCcontrolWithFocus = FindTabControlWithFocus(controlWithFocus);
if (tabCcontrolWithFocus == null)
return;
SetFocusOnNextControl(tabCcontrolWithFocus);
}
private TabControl FindTabControlWithFocus(Control controlWithFocus)
{
return _tabControls.FirstOrDefault(tabControl => tabControl.Control == controlWithFocus
|| tabControl.KeyboardFocusedControl == controlWithFocus);
}
private void SetFocusOnNextControl(TabControl tabControl)
{
if (_lastTabControl.KeyboardFocusedControl == tabControl.KeyboardFocusedControl)
_phoneApplicationPage.Focus();
else
{
var nextControl = _tabControls
.FirstOrDefault(c => c.Control.TabIndex > tabControl.Control.TabIndex);
var wasFocusSet = false;
if (nextControl != null)
wasFocusSet = nextControl.Control.Focus();
if (!wasFocusSet)
SetFocusOnNextControl(nextControl);
}
}
private static IEnumerable<DependencyObject> GetChildren(DependencyObject root)
{
var children = new List<DependencyObject> {root};
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
children.AddRange(GetChildren(VisualTreeHelper.GetChild(root, i)));
return children;
}
private class TabControl
{
public Control Control { get; set; }
public Control KeyboardFocusedControl { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment