123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- using System;
- using System.Collections.Generic;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using HandyControl.Data;
- using HandyControl.Tools;
- namespace HandyControl.Controls;
- public class TabPanel : Panel
- {
- private int _itemCount;
- /// <summary>
- /// 是否可以更新
- /// </summary>
- internal bool CanUpdate = true;
- /// <summary>
- /// 选项卡字典
- /// </summary>
- internal Dictionary<int, TabItem> ItemDic = new();
- public static readonly DependencyPropertyKey FluidMoveDurationPropertyKey =
- DependencyProperty.RegisterReadOnly("FluidMoveDuration", typeof(Duration), typeof(TabPanel),
- new PropertyMetadata(new Duration(TimeSpan.FromMilliseconds(0))));
- /// <summary>
- /// 流式行为持续时间
- /// </summary>
- public static readonly DependencyProperty FluidMoveDurationProperty =
- FluidMoveDurationPropertyKey.DependencyProperty;
- /// <summary>
- /// 流式行为持续时间
- /// </summary>
- public Duration FluidMoveDuration
- {
- get => (Duration) GetValue(FluidMoveDurationProperty);
- set => SetValue(FluidMoveDurationProperty, value);
- }
- /// <summary>
- /// 是否将标签填充
- /// </summary>
- public static readonly DependencyProperty IsTabFillEnabledProperty = DependencyProperty.Register(
- nameof(IsTabFillEnabled), typeof(bool), typeof(TabPanel), new PropertyMetadata(ValueBoxes.FalseBox));
- /// <summary>
- /// 是否将标签填充
- /// </summary>
- public bool IsTabFillEnabled
- {
- get => (bool) GetValue(IsTabFillEnabledProperty);
- set => SetValue(IsTabFillEnabledProperty, ValueBoxes.BooleanBox(value));
- }
- /// <summary>
- /// 标签宽度
- /// </summary>
- public static readonly DependencyProperty TabItemWidthProperty = DependencyProperty.Register(
- nameof(TabItemWidth), typeof(double), typeof(TabPanel), new PropertyMetadata(200.0));
- /// <summary>
- /// 标签宽度
- /// </summary>
- public double TabItemWidth
- {
- get => (double) GetValue(TabItemWidthProperty);
- set => SetValue(TabItemWidthProperty, value);
- }
- /// <summary>
- /// 标签高度
- /// </summary>
- public static readonly DependencyProperty TabItemHeightProperty = DependencyProperty.Register(
- nameof(TabItemHeight), typeof(double), typeof(TabPanel), new PropertyMetadata(30.0));
- /// <summary>
- /// 标签高度
- /// </summary>
- public double TabItemHeight
- {
- get => (double) GetValue(TabItemHeightProperty);
- set => SetValue(TabItemHeightProperty, value);
- }
- /// <summary>
- /// 是否可以强制更新
- /// </summary>
- internal bool ForceUpdate;
- private Size _oldSize;
- /// <summary>
- /// 是否已经加载
- /// </summary>
- 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 = ArithmeticHelper.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 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;
- };
- }
- }
|