Доработан winui
This commit is contained in:
@@ -13,21 +13,6 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Lattice.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Представляет кастомный контрол вкладок с поддержкой всех позиций размещения панели вкладок.
|
||||
/// Реализует интерфейс <see cref="IDockLeafControl"/> для интеграции с системой докинга.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Контрол обеспечивает отображение коллекции вкладок с возможностью навигации между ними,
|
||||
/// закрытия вкладок и изменения порядка. Поддерживает все четыре позиции размещения панели
|
||||
/// вкладок: сверху, снизу, слева и справа.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Контрол автоматически синхронизирует свое состояние с моделью данных <see cref="DockLeaf"/>
|
||||
/// и обеспечивает двустороннюю привязку данных через механизм INotifyPropertyChanged.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
{
|
||||
private readonly PropertyChangedEventHandler _modelPropertyChangedHandler;
|
||||
@@ -44,9 +29,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
private bool _showCloseButtons = true;
|
||||
private bool _canReorderTabs = true;
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр класса <see cref="LatticeTabControl"/>.
|
||||
/// </summary>
|
||||
public LatticeTabControl()
|
||||
{
|
||||
this.DefaultStyleKey = typeof(LatticeTabControl);
|
||||
@@ -54,7 +36,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
this.DataContextChanged += OnDataContextChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDockElement? Model
|
||||
{
|
||||
get => _model;
|
||||
@@ -68,7 +49,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LayoutManager? LayoutManager
|
||||
{
|
||||
get => _layoutManager;
|
||||
@@ -80,7 +60,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDockContextManager? ContextManager
|
||||
{
|
||||
get => _contextManager;
|
||||
@@ -92,7 +71,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
@@ -104,7 +82,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsActive
|
||||
{
|
||||
get => _isActive;
|
||||
@@ -116,7 +93,9 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanDrag => true;
|
||||
public bool CanDrop => true;
|
||||
|
||||
public TabPlacement TabPlacement
|
||||
{
|
||||
get => _tabPlacement;
|
||||
@@ -131,7 +110,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ShowCloseButtons
|
||||
{
|
||||
get => _showCloseButtons;
|
||||
@@ -146,7 +124,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanReorderTabs
|
||||
{
|
||||
get => _canReorderTabs;
|
||||
@@ -160,7 +137,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDockContent? ActiveContent
|
||||
{
|
||||
get => _model?.ActiveContent;
|
||||
@@ -173,19 +149,14 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object? PrepareDragData() => Model;
|
||||
public bool HandleDrop(object data, DockPosition position) => false;
|
||||
|
||||
public event EventHandler<ActiveContentChangedEventArgs>? ActiveContentChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<ContentClosingEventArgs>? ContentClosing;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<TabsReorderedEventArgs>? TabsReordered;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
@@ -203,17 +174,11 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
UpdateTabHeaders();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обрабатывает изменение контекста данных контрола.
|
||||
/// </summary>
|
||||
private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
|
||||
{
|
||||
Model = args.NewValue as DockLeaf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Присоединяет модель данных к контролу.
|
||||
/// </summary>
|
||||
private void AttachModel()
|
||||
{
|
||||
if (_model != null)
|
||||
@@ -232,9 +197,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Отсоединяет модель данных от контрола.
|
||||
/// </summary>
|
||||
private void DetachModel()
|
||||
{
|
||||
if (_model != null)
|
||||
@@ -250,9 +212,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обрабатывает изменения свойств модели данных.
|
||||
/// </summary>
|
||||
private void OnModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
@@ -274,17 +233,11 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обрабатывает изменения коллекции вкладок.
|
||||
/// </summary>
|
||||
private void OnChildrenCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateTabHeaders();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет положение панели вкладок.
|
||||
/// </summary>
|
||||
private void UpdateTabPlacement()
|
||||
{
|
||||
if (_rootGrid == null || _model == null) return;
|
||||
@@ -322,10 +275,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
UpdateElementPositions();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет ориентацию списка заголовков вкладок.
|
||||
/// </summary>
|
||||
/// <param name="orientation">Новая ориентация списка.</param>
|
||||
private void UpdateHeaderListOrientation(Orientation orientation)
|
||||
{
|
||||
if (_tabHeaderList?.ItemsPanelRoot is StackPanel stackPanel)
|
||||
@@ -334,9 +283,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет позиции элементов в сетке.
|
||||
/// </summary>
|
||||
private void UpdateElementPositions()
|
||||
{
|
||||
if (_rootGrid == null || _tabHeaderList == null || _contentControl == null) return;
|
||||
@@ -373,9 +319,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет заголовки вкладок.
|
||||
/// </summary>
|
||||
private void UpdateTabHeaders()
|
||||
{
|
||||
if (_tabHeaderList == null || _model == null) return;
|
||||
@@ -391,11 +334,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
UpdateSelectedTab();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает элемент заголовка вкладки.
|
||||
/// </summary>
|
||||
/// <param name="content">Содержимое вкладки.</param>
|
||||
/// <returns>Созданный элемент заголовка.</returns>
|
||||
private ListBoxItem CreateTabHeaderItem(IDockContent content)
|
||||
{
|
||||
var item = new ListBoxItem
|
||||
@@ -411,18 +349,12 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
if (e.GetCurrentPoint(item).Properties.IsLeftButtonPressed)
|
||||
{
|
||||
ActiveContent = content;
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает содержимое заголовка вкладки.
|
||||
/// </summary>
|
||||
/// <param name="content">Содержимое вкладки.</param>
|
||||
/// <returns>Созданное содержимое заголовка.</returns>
|
||||
private UIElement CreateTabHeaderContent(IDockContent content)
|
||||
{
|
||||
var grid = new Grid();
|
||||
@@ -455,7 +387,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
closeButton.Click += (sender, e) =>
|
||||
{
|
||||
CloseContent(content);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
Grid.SetColumn(closeButton, 1);
|
||||
@@ -465,9 +396,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
return grid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет выбранную вкладку.
|
||||
/// </summary>
|
||||
private void UpdateSelectedTab()
|
||||
{
|
||||
if (_tabHeaderList == null || _model == null) return;
|
||||
@@ -486,9 +414,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обрабатывает изменение выбора вкладки.
|
||||
/// </summary>
|
||||
private void OnTabSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (_tabHeaderList?.SelectedItem is ListBoxItem selectedItem &&
|
||||
@@ -505,7 +430,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void AddContent(IDockContent content)
|
||||
{
|
||||
if (_model != null && !_model.Children.Contains(content))
|
||||
@@ -515,7 +439,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RemoveContent(IDockContent content)
|
||||
{
|
||||
if (_model != null && _model.Children.Contains(content))
|
||||
@@ -525,7 +448,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CloseContent(IDockContent content)
|
||||
{
|
||||
var args = new ContentClosingEventArgs(content);
|
||||
@@ -540,7 +462,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void CloseAllExcept(IDockContent exceptContent)
|
||||
{
|
||||
if (_model == null) return;
|
||||
@@ -555,7 +476,6 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void CloseAll()
|
||||
{
|
||||
if (_model == null) return;
|
||||
@@ -567,23 +487,17 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Refresh()
|
||||
{
|
||||
UpdateTabHeaders();
|
||||
UpdateTabPlacement();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ApplyTheme(IDockTheme theme)
|
||||
{
|
||||
if (theme != null)
|
||||
{
|
||||
// TODO: Реализовать применение темы к стилям контрола
|
||||
}
|
||||
// TODO: Реализовать применение темы
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnModelPropertyChanged(string propertyName)
|
||||
{
|
||||
if (_model != null)
|
||||
@@ -592,15 +506,11 @@ public sealed class LatticeTabControl : Control, IDockLeafControl, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вызывает событие изменения свойства.
|
||||
/// </summary>
|
||||
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
|
||||
Reference in New Issue
Block a user