csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.2 KiB
150 lines
5.2 KiB
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
|
|
using Avalonia.Animation;
|
|
using Avalonia.Controls.Generators;
|
|
using Avalonia.Controls.Primitives;
|
|
using Avalonia.Controls.Templates;
|
|
|
|
namespace Avalonia.Controls
|
|
{
|
|
/// <summary>
|
|
/// A tab control that displays a tab strip along with the content of the selected tab.
|
|
/// </summary>
|
|
public class TabControl : SelectingItemsControl
|
|
{
|
|
/// <summary>
|
|
/// Defines the <see cref="Transition"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<IPageTransition> TransitionProperty =
|
|
Avalonia.Controls.Carousel.TransitionProperty.AddOwner<TabControl>();
|
|
|
|
/// <summary>
|
|
/// Defines an <see cref="IMemberSelector"/> that selects the content of a <see cref="TabItem"/>.
|
|
/// </summary>
|
|
public static readonly IMemberSelector ContentSelector =
|
|
new FuncMemberSelector<object, object>(SelectContent);
|
|
|
|
/// <summary>
|
|
/// Defines an <see cref="IMemberSelector"/> that selects the header of a <see cref="TabItem"/>.
|
|
/// </summary>
|
|
public static readonly IMemberSelector HeaderSelector =
|
|
new FuncMemberSelector<object, object>(SelectHeader);
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="TabStripPlacement"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<Dock> TabStripPlacementProperty =
|
|
AvaloniaProperty.Register<TabControl, Dock>(nameof(TabStripPlacement), defaultValue: Dock.Top);
|
|
|
|
/// <summary>
|
|
/// Initializes static members of the <see cref="TabControl"/> class.
|
|
/// </summary>
|
|
static TabControl()
|
|
{
|
|
SelectionModeProperty.OverrideDefaultValue<TabControl>(SelectionMode.AlwaysSelected);
|
|
FocusableProperty.OverrideDefaultValue<TabControl>(false);
|
|
AffectsMeasure(TabStripPlacementProperty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the pages portion of the <see cref="TabControl"/>'s template.
|
|
/// </summary>
|
|
public IControl Pages
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the tab strip portion of the <see cref="TabControl"/>'s template.
|
|
/// </summary>
|
|
public IControl TabStrip
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the transition to use when switching tabs.
|
|
/// </summary>
|
|
public IPageTransition Transition
|
|
{
|
|
get { return GetValue(TransitionProperty); }
|
|
set { SetValue(TransitionProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the tabstrip placement of the tabcontrol.
|
|
/// </summary>
|
|
public Dock TabStripPlacement
|
|
{
|
|
get { return GetValue(TabStripPlacementProperty); }
|
|
set { SetValue(TabStripPlacementProperty, value); }
|
|
}
|
|
|
|
protected override IItemContainerGenerator CreateItemContainerGenerator()
|
|
{
|
|
// TabControl doesn't actually create items - instead its TabStrip and Carousel
|
|
// children create the items. However we want it to be a SelectingItemsControl
|
|
// so that it has the Items/SelectedItem etc properties. In this case, we can
|
|
// return a null ItemContainerGenerator to disable the creation of item containers.
|
|
return null;
|
|
}
|
|
|
|
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
|
|
{
|
|
base.OnTemplateApplied(e);
|
|
|
|
TabStrip = e.NameScope.Find<IControl>("PART_TabStrip");
|
|
Pages = e.NameScope.Find<IControl>("PART_Content");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Selects the content of a tab item.
|
|
/// </summary>
|
|
/// <param name="o">The tab item.</param>
|
|
/// <returns>The content.</returns>
|
|
private static object SelectContent(object o)
|
|
{
|
|
var content = o as IContentControl;
|
|
|
|
if (content != null)
|
|
{
|
|
return content.Content;
|
|
}
|
|
else
|
|
{
|
|
return o;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Selects the header of a tab item.
|
|
/// </summary>
|
|
/// <param name="o">The tab item.</param>
|
|
/// <returns>The content.</returns>
|
|
private static object SelectHeader(object o)
|
|
{
|
|
var headered = o as IHeadered;
|
|
var control = o as IControl;
|
|
|
|
if (headered != null)
|
|
{
|
|
return headered.Header ?? string.Empty;
|
|
}
|
|
else if (control != null)
|
|
{
|
|
// Non-headered control items should result in TabStripItems with empty content.
|
|
// If a TabStrip is created with non IHeadered controls as its items, don't try to
|
|
// display the control in the TabStripItem: the content portion will also try to
|
|
// display this control, resulting in dual-parentage breakage.
|
|
return string.Empty;
|
|
}
|
|
else
|
|
{
|
|
return o;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|