Files
Lattice/Lattice.UI.Docking.WinUI/Controls/AdvancedTabControl.cs
2026-02-01 09:26:13 +03:00

189 lines
7.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Lattice.Core.Docking.Models;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections.ObjectModel;
namespace Lattice.UI;
/// <summary>
/// Представляет расширенный контрол вкладок с поддержкой всех позиций размещения панели вкладок.
/// Обеспечивает отображение коллекции вкладок с возможностью навигации, закрытия и изменения порядка.
/// Поддерживает четыре позиции размещения: сверху, снизу, слева и справа.
/// </summary>
public sealed class AdvancedTabControl : Control
{
private Grid? _rootGrid;
private TabView? _tabView;
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="AdvancedTabControl"/>.
/// </summary>
public AdvancedTabControl()
{
DefaultStyleKey = typeof(AdvancedTabControl);
}
/// <summary>
/// Идентифицирует свойство зависимостей <see cref="ItemsSource"/>.
/// </summary>
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(nameof(ItemsSource), typeof(ObservableCollection<object>),
typeof(AdvancedTabControl), new PropertyMetadata(null));
/// <summary>
/// Идентифицирует свойство зависимостей <see cref="SelectedItem"/>.
/// </summary>
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(nameof(SelectedItem), typeof(object),
typeof(AdvancedTabControl), new PropertyMetadata(null));
/// <summary>
/// Идентифицирует свойство зависимостей <see cref="TabPlacement"/>.
/// </summary>
public static readonly DependencyProperty TabPlacementProperty =
DependencyProperty.Register(nameof(TabPlacement), typeof(TabPlacement),
typeof(AdvancedTabControl), new PropertyMetadata(TabPlacement.Top, OnTabPlacementChanged));
/// <summary>
/// Получает или задает источник данных для вкладок.
/// </summary>
public ObservableCollection<object> ItemsSource
{
get => (ObservableCollection<object>)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
/// <summary>
/// Получает или задает выбранный элемент вкладки.
/// </summary>
public object SelectedItem
{
get => GetValue(SelectedItemProperty);
set => SetValue(SelectedItemProperty, value);
}
/// <summary>
/// Получает или задает положение панели вкладок.
/// </summary>
public TabPlacement TabPlacement
{
get => (TabPlacement)GetValue(TabPlacementProperty);
set => SetValue(TabPlacementProperty, value);
}
/// <summary>
/// Вызывается при применении шаблона контрола.
/// </summary>
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_rootGrid = GetTemplateChild("PART_RootGrid") as Grid;
_tabView = GetTemplateChild("PART_TabView") as TabView;
UpdateTabPlacement();
}
/// <summary>
/// Обновляет положение панели вкладок в соответствии с текущим значением свойства <see cref="TabPlacement"/>.
/// </summary>
private void UpdateTabPlacement()
{
if (_rootGrid == null) return;
// Очищаем определения строк и столбцов
_rootGrid.RowDefinitions.Clear();
_rootGrid.ColumnDefinitions.Clear();
switch (TabPlacement)
{
case TabPlacement.Top:
SetupTopPlacement();
break;
case TabPlacement.Bottom:
SetupBottomPlacement();
break;
case TabPlacement.Left:
SetupLeftPlacement();
break;
case TabPlacement.Right:
SetupRightPlacement();
break;
}
}
/// <summary>
/// Настраивает размещение панели вкладок вверху.
/// </summary>
private void SetupTopPlacement()
{
_rootGrid!.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
_rootGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
if (_tabView != null)
{
Grid.SetRow(_tabView, 0);
Grid.SetColumn(_tabView, 0);
Grid.SetRowSpan(_tabView, 1);
}
}
/// <summary>
/// Настраивает размещение панели вкладок внизу.
/// </summary>
private void SetupBottomPlacement()
{
_rootGrid!.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
_rootGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
if (_tabView != null)
{
Grid.SetRow(_tabView, 1);
Grid.SetColumn(_tabView, 0);
}
}
/// <summary>
/// Настраивает размещение панели вкладок слева.
/// </summary>
private void SetupLeftPlacement()
{
_rootGrid!.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
_rootGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
if (_tabView != null)
{
// Для вертикального размещения требуется специальный стиль
_tabView.Style = Application.Current.Resources["VerticalTabViewStyle"] as Style;
Grid.SetRow(_tabView, 0);
Grid.SetColumn(_tabView, 0);
}
}
/// <summary>
/// Настраивает размещение панели вкладок справа.
/// </summary>
private void SetupRightPlacement()
{
_rootGrid!.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
_rootGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
if (_tabView != null)
{
_tabView.Style = Application.Current.Resources["VerticalTabViewStyle"] as Style;
Grid.SetRow(_tabView, 0);
Grid.SetColumn(_tabView, 1);
}
}
/// <summary>
/// Обрабатывает изменение значения свойства <see cref="TabPlacement"/>.
/// </summary>
/// <param name="d">Объект зависимости, значение которого изменилось.</param>
/// <param name="e">Данные о изменении свойства.</param>
private static void OnTabPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is AdvancedTabControl control)
control.UpdateTabPlacement();
}
}