|
|
|
@ -6,12 +6,14 @@ using System.Collections.Generic; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Text; |
|
|
|
using System.Windows.Controls; |
|
|
|
|
|
|
|
using System.Windows; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows.Media; |
|
|
|
using System.Windows.Controls; |
|
|
|
|
|
|
|
using System.Windows.Controls.Primitives; |
|
|
|
using System.Windows.Data; |
|
|
|
using System.Windows.Data; |
|
|
|
using System.Windows.Documents; |
|
|
|
using System.Windows.Documents; |
|
|
|
using System.Windows.Input; |
|
|
|
using System.Windows.Input; |
|
|
|
|
|
|
|
using System.Windows.Media; |
|
|
|
|
|
|
|
using System.Windows.Threading; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.TreeView |
|
|
|
namespace ICSharpCode.TreeView |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -158,6 +160,64 @@ namespace ICSharpCode.TreeView |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
switch (e.Key) { |
|
|
|
|
|
|
|
case Key.Left: |
|
|
|
|
|
|
|
case Key.Right: |
|
|
|
|
|
|
|
SharpTreeViewItem container = e.OriginalSource as SharpTreeViewItem; |
|
|
|
|
|
|
|
if (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this) { |
|
|
|
|
|
|
|
bool newExpanded = (e.Key == Key.Right); |
|
|
|
|
|
|
|
if (container.Node.IsExpanded != newExpanded) { |
|
|
|
|
|
|
|
container.Node.IsExpanded = newExpanded; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// already in collapsed/expanded - jump to parent/first child:
|
|
|
|
|
|
|
|
if (e.Key == Key.Right) { |
|
|
|
|
|
|
|
container.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); |
|
|
|
|
|
|
|
} else if (container.Node.Parent != null) { |
|
|
|
|
|
|
|
this.FocusNode(container.Node.Parent); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
e.Handled = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
base.OnKeyDown(e); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void FocusNode(SharpTreeNode node) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (node == null) |
|
|
|
|
|
|
|
throw new ArgumentNullException("node"); |
|
|
|
|
|
|
|
ScrollIntoView(node); |
|
|
|
|
|
|
|
// WPF's ScrollIntoView() uses the same if/dispatcher construct, so we call OnFocusItem() after the item was brought into view.
|
|
|
|
|
|
|
|
if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) { |
|
|
|
|
|
|
|
OnFocusItem(node); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new DispatcherOperationCallback(this.OnFocusItem), node); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void ScrollIntoView(SharpTreeNode node) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (node == null) |
|
|
|
|
|
|
|
throw new ArgumentNullException("node"); |
|
|
|
|
|
|
|
foreach (SharpTreeNode ancestor in node.Ancestors()) |
|
|
|
|
|
|
|
ancestor.IsExpanded = true; |
|
|
|
|
|
|
|
base.ScrollIntoView(node); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
object OnFocusItem(object item) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FrameworkElement element = this.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; |
|
|
|
|
|
|
|
if (element != null) { |
|
|
|
|
|
|
|
element.Focus(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#region Track selection
|
|
|
|
#region Track selection
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnSelectionChanged(SelectionChangedEventArgs e) |
|
|
|
protected override void OnSelectionChanged(SelectionChangedEventArgs e) |
|
|
|
|