From 9ae20bd73bcd1baafdbe4741a3917c8b0ffa58a0 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 4 Dec 2014 17:55:37 +0100 Subject: [PATCH] Hacky keyboard navigation for TreeView. --- Perspex.Controls/TreeView.cs | 100 ++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/Perspex.Controls/TreeView.cs b/Perspex.Controls/TreeView.cs index 85ead34278..85f0e6573e 100644 --- a/Perspex.Controls/TreeView.cs +++ b/Perspex.Controls/TreeView.cs @@ -6,10 +6,9 @@ namespace Perspex.Controls { - using System.Linq; - using System.Reactive.Linq; + using System.Collections; + using System.Collections.Generic; using Perspex.Controls.Generators; - using Perspex.Controls.Presenters; using Perspex.Controls.Primitives; using Perspex.Input; @@ -20,28 +19,77 @@ namespace Perspex.Controls return new TreeItemContainerGenerator(this); } - //protected override void OnPointerPressed(PointerEventArgs e) - //{ - // IVisual source = (IVisual)e.Source; - // ContentPresenter contentPresenter = source.GetVisualAncestors() - // .OfType() - // .FirstOrDefault(); - - // if (contentPresenter != null) - // { - // TreeViewItem container = contentPresenter.TemplatedParent as TreeViewItem; - - // if (container != null) - // { - // foreach (var i in this.GetVisualDescendents().OfType()) - // { - // i.IsSelected = i == container; - // } - - // this.SelectedItem = this.ItemContainerGenerator.GetItemForContainer(container); - // } - // } - - //} + protected override void MoveSelection(FocusNavigationDirection direction) + { + // TODO: Up and down movement is a *HACK* and probably pretty slow. Probably needs + // rewriting at some point. + if (this.SelectedItem != null) + { + switch (direction) + { + case FocusNavigationDirection.Up: + { + var list = this.Flatten(); + var index = list.IndexOf(this.SelectedItem); + + if (index > 0) + { + this.SelectedItem = list[index - 1]; + } + break; + } + + case FocusNavigationDirection.Down: + { + var list = this.Flatten(); + var index = list.IndexOf(this.SelectedItem); + + if (index + 1 < list.Count) + { + this.SelectedItem = list[index + 1]; + } + break; + } + + case FocusNavigationDirection.Left: + { + var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); + node.IsExpanded = false; + break; + } + + case FocusNavigationDirection.Right: + { + var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); + node.IsExpanded = true; + break; + } + } + } + } + + List Flatten() + { + var result = new List(); + this.Flatten(this.Items, result); + return result; + } + + void Flatten(IEnumerable items, List result) + { + if (items != null) + { + foreach (object item in items) + { + var container = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(item); + result.Add(item); + + if (container.IsExpanded) + { + this.Flatten(container.Items, result); + } + } + } + } } }