TabControl.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright (c) The Avalonia 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 Avalonia.Controls.Generators;
  5. using Avalonia.Controls.Mixins;
  6. using Avalonia.Controls.Presenters;
  7. using Avalonia.Controls.Primitives;
  8. using Avalonia.Controls.Templates;
  9. using Avalonia.Input;
  10. using Avalonia.Layout;
  11. using Avalonia.VisualTree;
  12. namespace Avalonia.Controls
  13. {
  14. /// <summary>
  15. /// A tab control that displays a tab strip along with the content of the selected tab.
  16. /// </summary>
  17. public class TabControl : SelectingItemsControl
  18. {
  19. /// <summary>
  20. /// Defines the <see cref="TabStripPlacement"/> property.
  21. /// </summary>
  22. public static readonly StyledProperty<Dock> TabStripPlacementProperty =
  23. AvaloniaProperty.Register<TabControl, Dock>(nameof(TabStripPlacement), defaultValue: Dock.Top);
  24. /// <summary>
  25. /// Defines the <see cref="HorizontalContentAlignment"/> property.
  26. /// </summary>
  27. public static readonly StyledProperty<HorizontalAlignment> HorizontalContentAlignmentProperty =
  28. ContentControl.HorizontalContentAlignmentProperty.AddOwner<TabControl>();
  29. /// <summary>
  30. /// Defines the <see cref="VerticalContentAlignment"/> property.
  31. /// </summary>
  32. public static readonly StyledProperty<VerticalAlignment> VerticalContentAlignmentProperty =
  33. ContentControl.VerticalContentAlignmentProperty.AddOwner<TabControl>();
  34. /// <summary>
  35. /// Defines the <see cref="ContentTemplate"/> property.
  36. /// </summary>
  37. public static readonly StyledProperty<IDataTemplate> ContentTemplateProperty =
  38. ContentControl.ContentTemplateProperty.AddOwner<TabControl>();
  39. /// <summary>
  40. /// The selected content property
  41. /// </summary>
  42. public static readonly StyledProperty<object> SelectedContentProperty =
  43. AvaloniaProperty.Register<TabControl, object>(nameof(SelectedContent));
  44. /// <summary>
  45. /// The selected content template property
  46. /// </summary>
  47. public static readonly StyledProperty<IDataTemplate> SelectedContentTemplateProperty =
  48. AvaloniaProperty.Register<TabControl, IDataTemplate>(nameof(SelectedContentTemplate));
  49. /// <summary>
  50. /// The default value for the <see cref="ItemsControl.ItemsPanel"/> property.
  51. /// </summary>
  52. private static readonly FuncTemplate<IPanel> DefaultPanel =
  53. new FuncTemplate<IPanel>(() => new WrapPanel());
  54. /// <summary>
  55. /// Initializes static members of the <see cref="TabControl"/> class.
  56. /// </summary>
  57. static TabControl()
  58. {
  59. SelectionModeProperty.OverrideDefaultValue<TabControl>(SelectionMode.AlwaysSelected);
  60. ItemsPanelProperty.OverrideDefaultValue<TabControl>(DefaultPanel);
  61. AffectsMeasure<TabControl>(TabStripPlacementProperty);
  62. ContentControlMixin.Attach<TabControl>(
  63. SelectedContentProperty,
  64. x => x.LogicalChildren,
  65. "PART_SelectedContentHost");
  66. }
  67. /// <summary>
  68. /// Gets or sets the horizontal alignment of the content within the control.
  69. /// </summary>
  70. public HorizontalAlignment HorizontalContentAlignment
  71. {
  72. get { return GetValue(HorizontalContentAlignmentProperty); }
  73. set { SetValue(HorizontalContentAlignmentProperty, value); }
  74. }
  75. /// <summary>
  76. /// Gets or sets the vertical alignment of the content within the control.
  77. /// </summary>
  78. public VerticalAlignment VerticalContentAlignment
  79. {
  80. get { return GetValue(VerticalContentAlignmentProperty); }
  81. set { SetValue(VerticalContentAlignmentProperty, value); }
  82. }
  83. /// <summary>
  84. /// Gets or sets the tabstrip placement of the TabControl.
  85. /// </summary>
  86. public Dock TabStripPlacement
  87. {
  88. get { return GetValue(TabStripPlacementProperty); }
  89. set { SetValue(TabStripPlacementProperty, value); }
  90. }
  91. /// <summary>
  92. /// Gets or sets the default data template used to display the content of the selected tab.
  93. /// </summary>
  94. public IDataTemplate ContentTemplate
  95. {
  96. get { return GetValue(ContentTemplateProperty); }
  97. set { SetValue(ContentTemplateProperty, value); }
  98. }
  99. /// <summary>
  100. /// Gets or sets the content of the selected tab.
  101. /// </summary>
  102. /// <value>
  103. /// The content of the selected tab.
  104. /// </value>
  105. public object SelectedContent
  106. {
  107. get { return GetValue(SelectedContentProperty); }
  108. internal set { SetValue(SelectedContentProperty, value); }
  109. }
  110. /// <summary>
  111. /// Gets or sets the content template for the selected tab.
  112. /// </summary>
  113. /// <value>
  114. /// The content template of the selected tab.
  115. /// </value>
  116. public IDataTemplate SelectedContentTemplate
  117. {
  118. get { return GetValue(SelectedContentTemplateProperty); }
  119. internal set { SetValue(SelectedContentTemplateProperty, value); }
  120. }
  121. internal ItemsPresenter ItemsPresenterPart { get; private set; }
  122. internal ContentPresenter ContentPart { get; private set; }
  123. protected override IItemContainerGenerator CreateItemContainerGenerator()
  124. {
  125. return new TabItemContainerGenerator(this);
  126. }
  127. protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
  128. {
  129. base.OnTemplateApplied(e);
  130. ItemsPresenterPart = e.NameScope.Get<ItemsPresenter>("PART_ItemsPresenter");
  131. ContentPart = e.NameScope.Get<ContentPresenter>("PART_SelectedContentHost");
  132. }
  133. /// <inheritdoc/>
  134. protected override void OnGotFocus(GotFocusEventArgs e)
  135. {
  136. base.OnGotFocus(e);
  137. if (e.NavigationMethod == NavigationMethod.Directional)
  138. {
  139. e.Handled = UpdateSelectionFromEventSource(e.Source);
  140. }
  141. }
  142. /// <inheritdoc/>
  143. protected override void OnPointerPressed(PointerPressedEventArgs e)
  144. {
  145. base.OnPointerPressed(e);
  146. if (e.MouseButton == MouseButton.Left && e.Pointer.Type == PointerType.Mouse)
  147. {
  148. e.Handled = UpdateSelectionFromEventSource(e.Source);
  149. }
  150. }
  151. protected override void OnPointerReleased(PointerReleasedEventArgs e)
  152. {
  153. if (e.MouseButton == MouseButton.Left && e.Pointer.Type != PointerType.Mouse)
  154. {
  155. var container = GetContainerFromEventSource(e.Source);
  156. if (container != null
  157. && container.GetVisualsAt(e.GetPosition(container))
  158. .Any(c => container == c || container.IsVisualAncestorOf(c)))
  159. {
  160. e.Handled = UpdateSelectionFromEventSource(e.Source);
  161. }
  162. }
  163. }
  164. }
  165. }