using BPASmartClient.MilkWithTea.Data; using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace BPASmartClient.MilkWithTea.Control; public class TabPanel : Panel { private int _itemCount; /// /// 是否可以更新 /// internal bool CanUpdate = true; /// /// 选项卡字典 /// internal Dictionary ItemDic = new(); public static readonly DependencyPropertyKey FluidMoveDurationPropertyKey = DependencyProperty.RegisterReadOnly("FluidMoveDuration", typeof(Duration), typeof(TabPanel), new PropertyMetadata(new Duration(TimeSpan.FromMilliseconds(0)))); /// /// 流式行为持续时间 /// public static readonly DependencyProperty FluidMoveDurationProperty = FluidMoveDurationPropertyKey.DependencyProperty; /// /// 流式行为持续时间 /// public Duration FluidMoveDuration { get => (Duration) GetValue(FluidMoveDurationProperty); set => SetValue(FluidMoveDurationProperty, value); } /// /// 是否将标签填充 /// public static readonly DependencyProperty IsTabFillEnabledProperty = DependencyProperty.Register( "IsTabFillEnabled", typeof(bool), typeof(TabPanel), new PropertyMetadata(ValueBoxes.FalseBox)); /// /// 是否将标签填充 /// public bool IsTabFillEnabled { get => (bool) GetValue(IsTabFillEnabledProperty); set => SetValue(IsTabFillEnabledProperty, ValueBoxes.BooleanBox(value)); } /// /// 标签宽度 /// public static readonly DependencyProperty TabItemWidthProperty = DependencyProperty.Register( "TabItemWidth", typeof(double), typeof(TabPanel), new PropertyMetadata(200.0)); /// /// 标签宽度 /// public double TabItemWidth { get => (double) GetValue(TabItemWidthProperty); set => SetValue(TabItemWidthProperty, value); } /// /// 标签高度 /// public static readonly DependencyProperty TabItemHeightProperty = DependencyProperty.Register( "TabItemHeight", typeof(double), typeof(TabPanel), new PropertyMetadata(30.0)); /// /// 标签高度 /// public double TabItemHeight { get => (double) GetValue(TabItemHeightProperty); set => SetValue(TabItemHeightProperty, value); } /// /// 是否可以强制更新 /// internal bool ForceUpdate; private Size _oldSize; /// /// 是否已经加载 /// private bool _isLoaded; protected override Size MeasureOverride(Size constraint) { if ((_itemCount == InternalChildren.Count || !CanUpdate) && !ForceUpdate && !IsTabFillEnabled) return _oldSize; constraint.Height = TabItemHeight; _itemCount = InternalChildren.Count; var size = new Size(); ItemDic.Clear(); var count = InternalChildren.Count; if (count == 0) { _oldSize = new Size(); return _oldSize; } constraint.Width += InternalChildren.Count; var itemWidth = .0; var arr = new int[count]; if (!IsTabFillEnabled) { itemWidth = TabItemWidth; } else { if (TemplatedParent is TabControl tabControl) { arr = DivideInt2Arr((int) tabControl.ActualWidth + InternalChildren.Count, count); } } for (var index = 0; index < count; index++) { if (IsTabFillEnabled) { itemWidth = arr[index]; } if (InternalChildren[index] is TabItem tabItem) { tabItem.RenderTransform = new TranslateTransform(); tabItem.MaxWidth = itemWidth; var rect = new Rect { X = size.Width - tabItem.BorderThickness.Left, Width = itemWidth, Height = TabItemHeight }; tabItem.Arrange(rect); tabItem.ItemWidth = itemWidth - tabItem.BorderThickness.Left; tabItem.CurrentIndex = index; tabItem.TargetOffsetX = 0; ItemDic[index] = tabItem; size.Width += tabItem.ItemWidth; } } size.Height = constraint.Height; _oldSize = size; return _oldSize; } /// /// 平分一个整数到一个数组中 /// /// /// /// public static int[] DivideInt2Arr(int num, int count) { var arr = new int[count]; var div = num / count; var rest = num % count; for (var i = 0; i < count; i++) { arr[i] = div; } for (var i = 0; i < rest; i++) { arr[i] += 1; } return arr; } public TabPanel() { Loaded += (s, e) => { if (_isLoaded) return; ForceUpdate = true; Measure(new Size(DesiredSize.Width, ActualHeight)); ForceUpdate = false; foreach (var item in ItemDic.Values) { item.TabPanel = this; } _isLoaded = true; }; } }