189 lines
7.2 KiB
C#
189 lines
7.2 KiB
C#
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();
|
||
}
|
||
} |