// Copyright (c) The Perspex Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Linq; using Perspex.Controls.Generators; using Perspex.Controls.Mixins; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; using Perspex.Input; using Perspex.LogicalTree; namespace Perspex.Controls { /// /// An item in a . /// public class TreeViewItem : HeaderedItemsControl, ISelectable { /// /// Defines the property. /// public static readonly PerspexProperty IsExpandedProperty = PerspexProperty.Register("IsExpanded"); /// /// Defines the property. /// public static readonly PerspexProperty IsSelectedProperty = ListBoxItem.IsSelectedProperty.AddOwner(); private static readonly ITemplate DefaultPanel = new FuncTemplate(() => new StackPanel { [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, }); private TreeView _treeView; /// /// Initializes static members of the class. /// static TreeViewItem() { SelectableMixin.Attach(IsSelectedProperty); FocusableProperty.OverrideDefaultValue(true); ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); } /// /// Gets or sets a value indicating whether the item is expanded to show its children. /// public bool IsExpanded { get { return GetValue(IsExpandedProperty); } set { SetValue(IsExpandedProperty, value); } } /// /// Gets or sets the selection state of the item. /// public bool IsSelected { get { return GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } /// /// Gets the for the tree view. /// public new ITreeItemContainerGenerator ItemContainerGenerator => (ITreeItemContainerGenerator)base.ItemContainerGenerator; /// protected override IItemContainerGenerator CreateItemContainerGenerator() { return new TreeItemContainerGenerator( this, TreeViewItem.HeaderProperty, TreeViewItem.ItemsProperty, TreeViewItem.IsExpandedProperty, _treeView?.ItemContainerGenerator.Index ?? new TreeContainerIndex()); } /// protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { base.OnAttachedToLogicalTree(e); _treeView = this.GetLogicalAncestors().OfType().FirstOrDefault(); } protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) { base.OnDetachedFromLogicalTree(e); ItemContainerGenerator.Clear(); } /// protected override void OnKeyDown(KeyEventArgs e) { if (!e.Handled) { switch (e.Key) { case Key.Right: if (Items != null && Items.Cast().Any()) { IsExpanded = true; } e.Handled = true; break; case Key.Left: IsExpanded = false; e.Handled = true; break; } } base.OnKeyDown(e); } } }