TreeViewItem.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System.Linq;
  4. using Perspex.Controls.Generators;
  5. using Perspex.Controls.Mixins;
  6. using Perspex.Controls.Primitives;
  7. using Perspex.Controls.Templates;
  8. using Perspex.Input;
  9. using Perspex.LogicalTree;
  10. namespace Perspex.Controls
  11. {
  12. /// <summary>
  13. /// An item in a <see cref="TreeView"/>.
  14. /// </summary>
  15. public class TreeViewItem : HeaderedItemsControl, ISelectable
  16. {
  17. /// <summary>
  18. /// Defines the <see cref="IsExpanded"/> property.
  19. /// </summary>
  20. public static readonly PerspexProperty<bool> IsExpandedProperty =
  21. PerspexProperty.Register<TreeViewItem, bool>("IsExpanded");
  22. /// <summary>
  23. /// Defines the <see cref="IsSelected"/> property.
  24. /// </summary>
  25. public static readonly PerspexProperty<bool> IsSelectedProperty =
  26. ListBoxItem.IsSelectedProperty.AddOwner<TreeViewItem>();
  27. private static readonly ITemplate<IPanel> DefaultPanel =
  28. new FuncTemplate<IPanel>(() => new StackPanel
  29. {
  30. [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
  31. });
  32. private TreeView _treeView;
  33. /// <summary>
  34. /// Initializes static members of the <see cref="TreeViewItem"/> class.
  35. /// </summary>
  36. static TreeViewItem()
  37. {
  38. SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty);
  39. FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
  40. ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
  41. }
  42. /// <summary>
  43. /// Gets or sets a value indicating whether the item is expanded to show its children.
  44. /// </summary>
  45. public bool IsExpanded
  46. {
  47. get { return GetValue(IsExpandedProperty); }
  48. set { SetValue(IsExpandedProperty, value); }
  49. }
  50. /// <summary>
  51. /// Gets or sets the selection state of the item.
  52. /// </summary>
  53. public bool IsSelected
  54. {
  55. get { return GetValue(IsSelectedProperty); }
  56. set { SetValue(IsSelectedProperty, value); }
  57. }
  58. /// <summary>
  59. /// Gets the <see cref="ITreeItemContainerGenerator"/> for the tree view.
  60. /// </summary>
  61. public new ITreeItemContainerGenerator ItemContainerGenerator =>
  62. (ITreeItemContainerGenerator)base.ItemContainerGenerator;
  63. /// <inheritdoc/>
  64. protected override IItemContainerGenerator CreateItemContainerGenerator()
  65. {
  66. return new TreeItemContainerGenerator<TreeViewItem>(
  67. this,
  68. TreeViewItem.HeaderProperty,
  69. TreeViewItem.ItemsProperty,
  70. TreeViewItem.IsExpandedProperty,
  71. _treeView?.ItemContainerGenerator.Index ?? new TreeContainerIndex());
  72. }
  73. /// <inheritdoc/>
  74. protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
  75. {
  76. base.OnAttachedToLogicalTree(e);
  77. _treeView = this.GetLogicalAncestors().OfType<TreeView>().FirstOrDefault();
  78. }
  79. protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
  80. {
  81. base.OnDetachedFromLogicalTree(e);
  82. ItemContainerGenerator.Clear();
  83. }
  84. /// <inheritdoc/>
  85. protected override void OnKeyDown(KeyEventArgs e)
  86. {
  87. if (!e.Handled)
  88. {
  89. switch (e.Key)
  90. {
  91. case Key.Right:
  92. if (Items != null && Items.Cast<object>().Any())
  93. {
  94. IsExpanded = true;
  95. }
  96. e.Handled = true;
  97. break;
  98. case Key.Left:
  99. IsExpanded = false;
  100. e.Handled = true;
  101. break;
  102. }
  103. }
  104. base.OnKeyDown(e);
  105. }
  106. }
  107. }