mirror of
https://gitee.com/chinware/atomui.git
synced 2024-12-02 03:47:52 +08:00
完成 CardTabControl 标签布局类
完成 CardTabControl 标签布局类
This commit is contained in:
parent
c92a0f557f
commit
c939b25884
@ -103,6 +103,13 @@
|
|||||||
<atom:TabStripItem>Tab 2</atom:TabStripItem>
|
<atom:TabStripItem>Tab 2</atom:TabStripItem>
|
||||||
<atom:TabStripItem>Tab 3</atom:TabStripItem>
|
<atom:TabStripItem>Tab 3</atom:TabStripItem>
|
||||||
</atom:TabStrip>
|
</atom:TabStrip>
|
||||||
|
|
||||||
|
<atom:CardTabStrip TabAlignmentCenter="True">
|
||||||
|
<atom:TabStripItem>Tab 1</atom:TabStripItem>
|
||||||
|
<atom:TabStripItem>Tab 2</atom:TabStripItem>
|
||||||
|
<atom:TabStripItem>Tab 3</atom:TabStripItem>
|
||||||
|
</atom:CardTabStrip>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</showcase:ShowCaseItem>
|
</showcase:ShowCaseItem>
|
||||||
|
|
||||||
|
@ -27,14 +27,12 @@ internal class CardTabControlTheme : BaseTabControlTheme
|
|||||||
CreateTemplateParentBinding(alignWrapper, DockPanel.DockProperty, BaseTabControl.TabStripPlacementProperty);
|
CreateTemplateParentBinding(alignWrapper, DockPanel.DockProperty, BaseTabControl.TabStripPlacementProperty);
|
||||||
CreateTemplateParentBinding(alignWrapper, Panel.MarginProperty,TabControl.TabStripMarginProperty);
|
CreateTemplateParentBinding(alignWrapper, Panel.MarginProperty,TabControl.TabStripMarginProperty);
|
||||||
|
|
||||||
var cardTabStripContainer = new DockPanel()
|
var cardTabControlContainer = new TabsContainerPanel()
|
||||||
{
|
{
|
||||||
Name = TabsContainerPart,
|
Name = TabsContainerPart,
|
||||||
};
|
};
|
||||||
cardTabStripContainer.RegisterInNameScope(scope);
|
cardTabControlContainer.RegisterInNameScope(scope);
|
||||||
|
CreateTemplateParentBinding(cardTabControlContainer, TabsContainerPanel.TabStripPlacementProperty, TabStrip.TabStripPlacementProperty);
|
||||||
TokenResourceBinder.CreateTokenBinding(cardTabStripContainer, StackPanel.SpacingProperty,
|
|
||||||
TabControlResourceKey.CardGutter);
|
|
||||||
|
|
||||||
var tabScrollViewer = new TabControlScrollViewer()
|
var tabScrollViewer = new TabControlScrollViewer()
|
||||||
{
|
{
|
||||||
@ -64,6 +62,7 @@ internal class CardTabControlTheme : BaseTabControlTheme
|
|||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
Icon = addTabIcon
|
Icon = addTabIcon
|
||||||
};
|
};
|
||||||
|
DockPanel.SetDock(addTabButton, Dock.Right);
|
||||||
|
|
||||||
CreateTemplateParentBinding(addTabButton, IconButton.BorderThicknessProperty, CardTabControl.CardBorderThicknessProperty);
|
CreateTemplateParentBinding(addTabButton, IconButton.BorderThicknessProperty, CardTabControl.CardBorderThicknessProperty);
|
||||||
CreateTemplateParentBinding(addTabButton, IconButton.CornerRadiusProperty, CardTabControl.CardBorderRadiusProperty);
|
CreateTemplateParentBinding(addTabButton, IconButton.CornerRadiusProperty, CardTabControl.CardBorderRadiusProperty);
|
||||||
@ -73,10 +72,10 @@ internal class CardTabControlTheme : BaseTabControlTheme
|
|||||||
|
|
||||||
addTabButton.RegisterInNameScope(scope);
|
addTabButton.RegisterInNameScope(scope);
|
||||||
|
|
||||||
cardTabStripContainer.Children.Add(addTabButton);
|
cardTabControlContainer.TabScrollViewer = tabScrollViewer;
|
||||||
cardTabStripContainer.Children.Add(tabScrollViewer);
|
cardTabControlContainer.AddTabButton = addTabButton;
|
||||||
|
|
||||||
alignWrapper.Children.Add(cardTabStripContainer);
|
alignWrapper.Children.Add(cardTabControlContainer);
|
||||||
|
|
||||||
container.Children.Add(alignWrapper);
|
container.Children.Add(alignWrapper);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ internal class TabScrollContentPresenter : ScrollContentPresenter, ICustomHitTes
|
|||||||
var x = Offset.X;
|
var x = Offset.X;
|
||||||
var y = Offset.Y;
|
var y = Offset.Y;
|
||||||
var delta = e.Delta;
|
var delta = e.Delta;
|
||||||
|
|
||||||
if (TabStripPlacement == Dock.Top || TabStripPlacement == Dock.Bottom) {
|
if (TabStripPlacement == Dock.Top || TabStripPlacement == Dock.Bottom) {
|
||||||
delta = new Vector(delta.Y, delta.X);
|
delta = new Vector(delta.Y, delta.X);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ internal class BaseTabStripTheme : BaseControlTheme
|
|||||||
{
|
{
|
||||||
public const string FrameDecoratorPart = "PART_FrameDecorator";
|
public const string FrameDecoratorPart = "PART_FrameDecorator";
|
||||||
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
||||||
|
public const string TabsContainerPart = "PART_TabsContainer";
|
||||||
|
public const string AlignWrapperPart = "PART_AlignWrapper";
|
||||||
|
|
||||||
public BaseTabStripTheme(Type targetType) : base(targetType) { }
|
public BaseTabStripTheme(Type targetType) : base(targetType) { }
|
||||||
|
|
||||||
@ -50,9 +52,9 @@ internal class BaseTabStripTheme : BaseControlTheme
|
|||||||
// tabs 是否居中
|
// tabs 是否居中
|
||||||
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
||||||
{
|
{
|
||||||
var itemsPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart));
|
var tabsContainerStyle = new Style(selector => selector.Nesting().Template().Name(TabsContainerPart));
|
||||||
itemsPresenterStyle.Add(ItemsPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
|
tabsContainerStyle.Add(ItemsPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
|
||||||
tabAlignCenterStyle.Add(itemsPresenterStyle);
|
tabAlignCenterStyle.Add(tabsContainerStyle);
|
||||||
}
|
}
|
||||||
topStyle.Add(tabAlignCenterStyle);
|
topStyle.Add(tabAlignCenterStyle);
|
||||||
|
|
||||||
@ -69,9 +71,9 @@ internal class BaseTabStripTheme : BaseControlTheme
|
|||||||
// tabs 是否居中
|
// tabs 是否居中
|
||||||
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
||||||
{
|
{
|
||||||
var itemsPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart));
|
var tabsContainerStyle = new Style(selector => selector.Nesting().Template().Name(TabsContainerPart));
|
||||||
itemsPresenterStyle.Add(ItemsPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
|
tabsContainerStyle.Add(ItemsPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
|
||||||
tabAlignCenterStyle.Add(itemsPresenterStyle);
|
tabAlignCenterStyle.Add(tabsContainerStyle);
|
||||||
}
|
}
|
||||||
rightStyle.Add(tabAlignCenterStyle);
|
rightStyle.Add(tabAlignCenterStyle);
|
||||||
|
|
||||||
@ -86,9 +88,9 @@ internal class BaseTabStripTheme : BaseControlTheme
|
|||||||
// tabs 是否居中
|
// tabs 是否居中
|
||||||
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
||||||
{
|
{
|
||||||
var itemsPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart));
|
var tabsContainerStyle = new Style(selector => selector.Nesting().Template().Name(TabsContainerPart));
|
||||||
itemsPresenterStyle.Add(ItemsPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
|
tabsContainerStyle.Add(ItemsPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
|
||||||
tabAlignCenterStyle.Add(itemsPresenterStyle);
|
tabAlignCenterStyle.Add(tabsContainerStyle);
|
||||||
}
|
}
|
||||||
bottomStyle.Add(tabAlignCenterStyle);
|
bottomStyle.Add(tabAlignCenterStyle);
|
||||||
|
|
||||||
@ -105,9 +107,9 @@ internal class BaseTabStripTheme : BaseControlTheme
|
|||||||
// tabs 是否居中
|
// tabs 是否居中
|
||||||
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
var tabAlignCenterStyle = new Style(selector => selector.Nesting().PropertyEquals(TabStrip.TabAlignmentCenterProperty, true));
|
||||||
{
|
{
|
||||||
var itemsPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart));
|
var tabsContainerStyle = new Style(selector => selector.Nesting().Template().Name(TabsContainerPart));
|
||||||
itemsPresenterStyle.Add(ItemsPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
|
tabsContainerStyle.Add(ItemsPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
|
||||||
tabAlignCenterStyle.Add(itemsPresenterStyle);
|
tabAlignCenterStyle.Add(tabsContainerStyle);
|
||||||
}
|
}
|
||||||
leftStyle.Add(tabAlignCenterStyle);
|
leftStyle.Add(tabAlignCenterStyle);
|
||||||
|
|
||||||
|
@ -127,37 +127,10 @@ public class CardTabStrip : BaseTabStrip, IControlCustomStyle
|
|||||||
if (change.Property == SizeTypeProperty) {
|
if (change.Property == SizeTypeProperty) {
|
||||||
HandleSizeTypeChanged();
|
HandleSizeTypeChanged();
|
||||||
} else if (change.Property == TabStripPlacementProperty) {
|
} else if (change.Property == TabStripPlacementProperty) {
|
||||||
SetupCardTabStripContainer();
|
|
||||||
HandleTabStripPlacementChanged();
|
HandleTabStripPlacementChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupCardTabStripContainer(Size finalSize)
|
|
||||||
{
|
|
||||||
if (_cardTabStripContainer is not null) {
|
|
||||||
double addButtonOffset = 0;
|
|
||||||
double markOffset = 0;
|
|
||||||
if (TabStripPlacement == Dock.Top || TabStripPlacement == Dock.Bottom) {
|
|
||||||
addButtonOffset = _addTabButton?.Bounds.Right ?? 0;
|
|
||||||
markOffset = finalSize.Width;
|
|
||||||
if (addButtonOffset > markOffset) {
|
|
||||||
_cardTabStripContainer.ColumnDefinitions[0].Width = GridLength.Star;
|
|
||||||
} else {
|
|
||||||
_cardTabStripContainer.ColumnDefinitions[0].Width = GridLength.Auto;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addButtonOffset = _addTabButton?.Bounds.Bottom ?? 0;
|
|
||||||
markOffset = finalSize.Height;
|
|
||||||
if (addButtonOffset > markOffset) {
|
|
||||||
_cardTabStripContainer.RowDefinitions[0].Height = GridLength.Star;
|
|
||||||
} else {
|
|
||||||
_cardTabStripContainer.RowDefinitions[0].Height = GridLength.Auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IControlCustomStyle 实现
|
#region IControlCustomStyle 实现
|
||||||
|
|
||||||
void IControlCustomStyle.HandleTemplateApplied(INameScope scope)
|
void IControlCustomStyle.HandleTemplateApplied(INameScope scope)
|
||||||
@ -170,7 +143,6 @@ public class CardTabStrip : BaseTabStrip, IControlCustomStyle
|
|||||||
_addTabButton.Click += HandleAddButtonClicked;
|
_addTabButton.Click += HandleAddButtonClicked;
|
||||||
}
|
}
|
||||||
HandleSizeTypeChanged();
|
HandleSizeTypeChanged();
|
||||||
SetupCardTabStripContainer();
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -193,56 +165,9 @@ public class CardTabStrip : BaseTabStrip, IControlCustomStyle
|
|||||||
protected override Size ArrangeOverride(Size finalSize)
|
protected override Size ArrangeOverride(Size finalSize)
|
||||||
{
|
{
|
||||||
var size = base.ArrangeOverride(finalSize);
|
var size = base.ArrangeOverride(finalSize);
|
||||||
SetupCardTabStripContainer(finalSize);
|
|
||||||
HandleTabStripPlacementChanged();
|
HandleTabStripPlacementChanged();
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupCardTabStripContainer()
|
|
||||||
{
|
|
||||||
if (TabStripPlacement == Dock.Top ||
|
|
||||||
TabStripPlacement == Dock.Bottom) {
|
|
||||||
if (_cardTabStripContainer is not null) {
|
|
||||||
_cardTabStripContainer.Children.Clear();
|
|
||||||
_cardTabStripContainer.RowDefinitions.Clear();
|
|
||||||
_cardTabStripContainer.ColumnDefinitions = new ColumnDefinitions()
|
|
||||||
{
|
|
||||||
new ColumnDefinition(GridLength.Auto),
|
|
||||||
new ColumnDefinition(GridLength.Auto),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_tabScrollViewer is not null) {
|
|
||||||
Grid.SetColumn(_tabScrollViewer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_addTabButton is not null) {
|
|
||||||
Grid.SetColumn(_addTabButton, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cardTabStripContainer!.Children.Add(_tabScrollViewer!);
|
|
||||||
_cardTabStripContainer.Children.Add(_addTabButton!);
|
|
||||||
} else {
|
|
||||||
if (_cardTabStripContainer is not null) {
|
|
||||||
_cardTabStripContainer.Children.Clear();
|
|
||||||
_cardTabStripContainer.ColumnDefinitions.Clear();
|
|
||||||
_cardTabStripContainer.RowDefinitions = new RowDefinitions()
|
|
||||||
{
|
|
||||||
new RowDefinition(GridLength.Auto),
|
|
||||||
new RowDefinition(GridLength.Auto),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (_tabScrollViewer is not null) {
|
|
||||||
Grid.SetRow(_tabScrollViewer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_addTabButton is not null) {
|
|
||||||
Grid.SetRow(_addTabButton, 1);
|
|
||||||
}
|
|
||||||
_cardTabStripContainer!.Children.Add(_tabScrollViewer!);
|
|
||||||
_cardTabStripContainer.Children.Add(_addTabButton!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleTabStripPlacementChanged()
|
private void HandleTabStripPlacementChanged()
|
||||||
{
|
{
|
||||||
|
@ -12,22 +12,24 @@ namespace AtomUI.Controls;
|
|||||||
[ControlThemeProvider]
|
[ControlThemeProvider]
|
||||||
internal class CardTabStripTheme : BaseTabStripTheme
|
internal class CardTabStripTheme : BaseTabStripTheme
|
||||||
{
|
{
|
||||||
public const string AddTabButtonPart = "PART_AddTabButton";
|
public const string AddTabButtonPart = "PART_AddTabButton";
|
||||||
public const string CardTabStripContainerPart = "PART_CardTabStripContainer";
|
public const string CardTabStripContainerPart = "PART_CardTabStripContainer";
|
||||||
public const string CardTabStripScrollViewerPart = "PART_CardTabStripScrollViewer";
|
public const string CardTabStripScrollViewerPart = "PART_CardTabStripScrollViewer";
|
||||||
|
|
||||||
public CardTabStripTheme() : base(typeof(CardTabStrip)) { }
|
public CardTabStripTheme() : base(typeof(CardTabStrip)) { }
|
||||||
|
|
||||||
protected override void NotifyBuildControlTemplate(BaseTabStrip baseTabStrip, INameScope scope, Border container)
|
protected override void NotifyBuildControlTemplate(BaseTabStrip baseTabStrip, INameScope scope, Border container)
|
||||||
{
|
{
|
||||||
var cardTabStripContainer = new Grid()
|
var alignWrapper = new Panel()
|
||||||
{
|
{
|
||||||
Name = CardTabStripContainerPart,
|
Name = AlignWrapperPart
|
||||||
|
};
|
||||||
|
var cardTabStripContainer = new TabsContainerPanel()
|
||||||
|
{
|
||||||
|
Name = TabsContainerPart,
|
||||||
};
|
};
|
||||||
cardTabStripContainer.RegisterInNameScope(scope);
|
cardTabStripContainer.RegisterInNameScope(scope);
|
||||||
|
CreateTemplateParentBinding(cardTabStripContainer, TabsContainerPanel.TabStripPlacementProperty, TabStrip.TabStripPlacementProperty);
|
||||||
TokenResourceBinder.CreateTokenBinding(cardTabStripContainer, StackPanel.SpacingProperty,
|
|
||||||
TabControlResourceKey.CardGutter);
|
|
||||||
|
|
||||||
var tabScrollViewer = new TabStripScrollViewer()
|
var tabScrollViewer = new TabStripScrollViewer()
|
||||||
{
|
{
|
||||||
@ -65,10 +67,13 @@ internal class CardTabStripTheme : BaseTabStripTheme
|
|||||||
TokenResourceBinder.CreateGlobalResourceBinding(addTabButton, IconButton.BorderBrushProperty, GlobalResourceKey.ColorBorderSecondary);
|
TokenResourceBinder.CreateGlobalResourceBinding(addTabButton, IconButton.BorderBrushProperty, GlobalResourceKey.ColorBorderSecondary);
|
||||||
|
|
||||||
addTabButton.RegisterInNameScope(scope);
|
addTabButton.RegisterInNameScope(scope);
|
||||||
|
|
||||||
|
cardTabStripContainer.TabScrollViewer = tabScrollViewer;
|
||||||
|
cardTabStripContainer.AddTabButton = addTabButton;
|
||||||
|
|
||||||
cardTabStripContainer.Children.Add(tabScrollViewer);
|
alignWrapper.Children.Add(cardTabStripContainer);
|
||||||
cardTabStripContainer.Children.Add(addTabButton);
|
|
||||||
container.Child = cardTabStripContainer;
|
container.Child = alignWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemsPresenter CreateTabStripContentPanel(INameScope scope)
|
private ItemsPresenter CreateTabStripContentPanel(INameScope scope)
|
||||||
|
@ -17,12 +17,23 @@ internal class TabStripTheme : BaseTabStripTheme
|
|||||||
|
|
||||||
protected override void NotifyBuildControlTemplate(BaseTabStrip baseTabStrip, INameScope scope, Border container)
|
protected override void NotifyBuildControlTemplate(BaseTabStrip baseTabStrip, INameScope scope, Border container)
|
||||||
{
|
{
|
||||||
var tabScrollViewer = new TabStripScrollViewer();
|
var alignWrapper = new Panel()
|
||||||
|
{
|
||||||
|
Name = AlignWrapperPart
|
||||||
|
};
|
||||||
|
alignWrapper.RegisterInNameScope(scope);
|
||||||
|
|
||||||
|
var tabScrollViewer = new TabStripScrollViewer()
|
||||||
|
{
|
||||||
|
Name = TabsContainerPart
|
||||||
|
};
|
||||||
CreateTemplateParentBinding(tabScrollViewer, BaseTabScrollViewer.TabStripPlacementProperty, TabStrip.TabStripPlacementProperty);
|
CreateTemplateParentBinding(tabScrollViewer, BaseTabScrollViewer.TabStripPlacementProperty, TabStrip.TabStripPlacementProperty);
|
||||||
var contentPanel = CreateTabStripContentPanel(scope);
|
var contentPanel = CreateTabStripContentPanel(scope);
|
||||||
tabScrollViewer.Content = contentPanel;
|
tabScrollViewer.Content = contentPanel;
|
||||||
tabScrollViewer.TabStrip = baseTabStrip;
|
tabScrollViewer.TabStrip = baseTabStrip;
|
||||||
container.Child = tabScrollViewer;
|
|
||||||
|
alignWrapper.Children.Add(tabScrollViewer);
|
||||||
|
container.Child = alignWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Panel CreateTabStripContentPanel(INameScope scope)
|
private Panel CreateTabStripContentPanel(INameScope scope)
|
||||||
|
115
src/AtomUI.Controls/TabControl/TabsContainerPanel.cs
Normal file
115
src/AtomUI.Controls/TabControl/TabsContainerPanel.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace AtomUI.Controls;
|
||||||
|
|
||||||
|
internal class TabsContainerPanel : Panel
|
||||||
|
{
|
||||||
|
#region 公共属性定义
|
||||||
|
|
||||||
|
public static readonly DirectProperty<TabsContainerPanel, BaseTabScrollViewer?> TabScrollViewerProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<TabsContainerPanel, BaseTabScrollViewer?>(nameof(TabScrollViewer),
|
||||||
|
o => o.TabScrollViewer,
|
||||||
|
(o, v) => o.TabScrollViewer = v);
|
||||||
|
|
||||||
|
private BaseTabScrollViewer? _tabScrollViewer;
|
||||||
|
public BaseTabScrollViewer? TabScrollViewer
|
||||||
|
{
|
||||||
|
get => _tabScrollViewer;
|
||||||
|
set => SetAndRaise(TabScrollViewerProperty, ref _tabScrollViewer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DirectProperty<TabsContainerPanel, IconButton?> AddTabButtonProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<TabsContainerPanel, IconButton?>(nameof(AddTabButton),
|
||||||
|
o => o.AddTabButton,
|
||||||
|
(o, v) => o.AddTabButton = v);
|
||||||
|
|
||||||
|
private IconButton? _addTabButton;
|
||||||
|
public IconButton? AddTabButton
|
||||||
|
{
|
||||||
|
get => _addTabButton;
|
||||||
|
set => SetAndRaise(AddTabButtonProperty, ref _addTabButton, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 内部属性定义
|
||||||
|
|
||||||
|
internal static readonly DirectProperty<TabsContainerPanel, Dock> TabStripPlacementProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<TabsContainerPanel, Dock>(nameof(TabStripPlacement),
|
||||||
|
o => o.TabStripPlacement,
|
||||||
|
(o, v) => o.TabStripPlacement = v);
|
||||||
|
|
||||||
|
private Dock _tabStripPlacement;
|
||||||
|
|
||||||
|
internal Dock TabStripPlacement
|
||||||
|
{
|
||||||
|
get => _tabStripPlacement;
|
||||||
|
set => SetAndRaise(TabStripPlacementProperty, ref _tabStripPlacement, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
static TabsContainerPanel()
|
||||||
|
{
|
||||||
|
AffectsMeasure<TabsContainerPanel>(TabScrollViewerProperty, AddTabButtonProperty);
|
||||||
|
AffectsArrange<TabsContainerPanel>(TabStripPlacementProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size ArrangeOverride(Size arrangeSize)
|
||||||
|
{
|
||||||
|
// TODO 暂时不做验证,默认认为两个元素都存在
|
||||||
|
// 理论上这里要报错,但是我们是内部使用
|
||||||
|
if (_tabScrollViewer is not null && _addTabButton is not null) {
|
||||||
|
if (TabStripPlacement == Dock.Top || TabStripPlacement == Dock.Bottom) {
|
||||||
|
var scrollViewerDesiredWidth = _tabScrollViewer.DesiredSize.Width;
|
||||||
|
var addTabButtonDesiredWidth = _addTabButton.DesiredSize.Width;
|
||||||
|
var totalDesiredWidth = scrollViewerDesiredWidth + addTabButtonDesiredWidth;
|
||||||
|
if (totalDesiredWidth > arrangeSize.Width) {
|
||||||
|
_tabScrollViewer.Arrange(new Rect(new Point(0, 0), new Size(arrangeSize.Width - addTabButtonDesiredWidth, arrangeSize.Height)));
|
||||||
|
_addTabButton.Arrange(new Rect(new Point(arrangeSize.Width - addTabButtonDesiredWidth, 0), _addTabButton.DesiredSize));
|
||||||
|
} else {
|
||||||
|
_tabScrollViewer.Arrange(new Rect(new Point(0, 0), _tabScrollViewer.DesiredSize));
|
||||||
|
_addTabButton.Arrange(new Rect(new Point(scrollViewerDesiredWidth, 0), _addTabButton.DesiredSize));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var scrollViewerDesiredHeight = _tabScrollViewer.DesiredSize.Height;
|
||||||
|
var addTabButtonDesiredHeight = _addTabButton.DesiredSize.Height;
|
||||||
|
var totalDesiredHeight = scrollViewerDesiredHeight + addTabButtonDesiredHeight;
|
||||||
|
if (totalDesiredHeight > arrangeSize.Height) {
|
||||||
|
_tabScrollViewer.Arrange(new Rect(new Point(0, 0), new Size(arrangeSize.Width, arrangeSize.Height - addTabButtonDesiredHeight)));
|
||||||
|
_addTabButton.Arrange(new Rect(new Point(0, arrangeSize.Width - addTabButtonDesiredHeight), _addTabButton.DesiredSize));
|
||||||
|
} else {
|
||||||
|
_tabScrollViewer.Arrange(new Rect(new Point(0, 0), _tabScrollViewer.DesiredSize));
|
||||||
|
_addTabButton.Arrange(new Rect(new Point(scrollViewerDesiredHeight, 0), _addTabButton.DesiredSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (arrangeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(change);
|
||||||
|
if (change.Property == TabScrollViewerProperty) {
|
||||||
|
var oldScrollViewer = change.GetOldValue<BaseTabScrollViewer?>();
|
||||||
|
if (oldScrollViewer is not null) {
|
||||||
|
Children.Remove(oldScrollViewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TabScrollViewer is not null) {
|
||||||
|
Children.Add(TabScrollViewer);
|
||||||
|
}
|
||||||
|
} else if (change.Property == AddTabButtonProperty) {
|
||||||
|
var oldAddTabButton = change.GetOldValue<IconButton?>();
|
||||||
|
if (oldAddTabButton is not null) {
|
||||||
|
Children.Remove(oldAddTabButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AddTabButton is not null) {
|
||||||
|
Children.Add(AddTabButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user