Browse Source

Fix TreeView selection.

TreeView cannot inherit from SelectingItemsControl as it makes no sense
to have a SelectedIndex property.
pull/58/head
Steven Kirk 11 years ago
parent
commit
e2c11c782d
  1. 133
      Perspex.Controls/TreeView.cs

133
Perspex.Controls/TreeView.cs

@ -6,20 +6,44 @@
namespace Perspex.Controls
{
using System.Collections;
using System.Collections.Generic;
using System;
using Perspex.Controls.Generators;
using Perspex.Controls.Primitives;
using Perspex.Input;
using Perspex.VisualTree;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class TreeView : SelectingItemsControl
public class TreeView : ItemsControl
{
public static readonly PerspexProperty<object> SelectedItemProperty =
PerspexProperty.Register<TreeView, object>("SelectedItem", coerce: CoerceSelectedItem);
static TreeView()
{
SelectedItemProperty.Changed.Subscribe(x =>
{
var control = x.Sender as TreeView;
if (control != null)
{
control.SelectedItemChanged(x.NewValue);
}
});
}
public object SelectedItem
{
get { return this.GetValue(SelectedItemProperty); }
set { this.SetValue(SelectedItemProperty, value); }
}
protected override ItemContainerGenerator CreateItemContainerGenerator()
{
return new TreeItemContainerGenerator<TreeViewItem>(this);
}
protected override void MoveSelection(FocusNavigationDirection direction)
protected virtual void MoveSelection(FocusNavigationDirection direction)
{
// TODO: Up and down movement is a *HACK* and probably pretty slow. Probably needs
// rewriting at some point.
@ -70,6 +94,85 @@ namespace Perspex.Controls
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (!e.Handled)
{
switch (e.Key)
{
case Key.Up:
this.MoveSelection(FocusNavigationDirection.Up);
break;
case Key.Down:
this.MoveSelection(FocusNavigationDirection.Down);
break;
case Key.Left:
this.MoveSelection(FocusNavigationDirection.Left);
break;
case Key.Right:
this.MoveSelection(FocusNavigationDirection.Right);
break;
default:
return;
}
var selected = this.SelectedItem;
if (selected != null)
{
var container = this.ItemContainerGenerator.GetContainerForItem(selected);
if (container != null)
{
container.BringIntoView();
FocusManager.Instance.Focus(container, true);
}
}
e.Handled = true;
}
}
protected override void OnPointerPressed(PointerPressEventArgs e)
{
IVisual source = (IVisual)e.Source;
var selectable = source.GetVisualAncestors()
.OfType<ISelectable>()
.OfType<Control>()
.FirstOrDefault();
if (selectable != null)
{
var item = this.ItemContainerGenerator.GetItemForContainer(selectable);
if (item != null)
{
this.SelectedItem = item;
selectable.BringIntoView();
FocusManager.Instance.Focus(selectable);
}
}
e.Handled = true;
}
private static object CoerceSelectedItem(PerspexObject o, object value)
{
//var control = o as SelectingItemsControl;
//if (control != null)
//{
// if (value != null && (control.Items == null || control.Items.IndexOf(value) == -1))
// {
// return null;
// }
//}
return value;
}
private List<object> Flatten()
{
var result = new List<object>();
@ -93,5 +196,25 @@ namespace Perspex.Controls
}
}
}
private void SelectedItemChanged(object selected)
{
var containers = this.ItemContainerGenerator.GetAll()
.Select(x => x.Item2)
.OfType<ISelectable>();
var selectedContainer = (selected != null) ?
this.ItemContainerGenerator.GetContainerForItem(selected) :
null;
if (this.Presenter != null && this.Presenter.Panel != null)
{
KeyboardNavigation.SetTabOnceActiveElement(this.Presenter.Panel, selectedContainer);
}
foreach (var item in containers)
{
item.IsSelected = item == selectedContainer;
}
}
}
}

Loading…
Cancel
Save