diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/ElementGroup.cs b/src/Shared/HandyControl_Shared/Controls/Panel/ElementGroup.cs new file mode 100644 index 00000000..58125c25 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Panel/ElementGroup.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.Windows; +using System.Windows.Controls; +using HandyControl.Tools; + +namespace HandyControl.Controls +{ + public class ElementGroup : SimpleStackPanel + { + private static readonly Dictionary> CornerRadiusDict; + + static ElementGroup() + { + var defaultCornerRadius = ResourceHelper.GetResourceInternal("DefaultCornerRadius"); + + CornerRadiusDict = new Dictionary> + { + [Orientation.Horizontal] = new() + { + [ChildLocation.Single] = defaultCornerRadius, + [ChildLocation.First] = new CornerRadius(defaultCornerRadius.TopLeft, 0, 0, defaultCornerRadius.BottomLeft), + [ChildLocation.Middle] = new CornerRadius(), + [ChildLocation.Last] = new CornerRadius(0, defaultCornerRadius.TopRight, defaultCornerRadius.BottomRight, 0) + }, + [Orientation.Vertical] = new() + { + [ChildLocation.Single] = defaultCornerRadius, + [ChildLocation.First] = new CornerRadius(defaultCornerRadius.TopLeft, defaultCornerRadius.TopRight, 0, 0), + [ChildLocation.Middle] = new CornerRadius(), + [ChildLocation.Last] = new CornerRadius(0, 0, defaultCornerRadius.BottomRight, defaultCornerRadius.BottomLeft) + } + }; + } + + protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) + { + base.OnVisualChildrenChanged(visualAdded, visualRemoved); + + if (visualAdded is UIElement elementAdded) + { + elementAdded.GotFocus += ElementAdded_GotFocus; + elementAdded.LostFocus += ElementAdded_LostFocus; + } + + if (visualRemoved is UIElement elementRemoved) + { + elementRemoved.GotFocus -= ElementAdded_GotFocus; + elementRemoved.LostFocus -= ElementAdded_LostFocus; + } + + var childrenCount = InternalChildren.Count; + if (childrenCount == 0) + { + return; + } + + var orientation = Orientation; + + if (childrenCount == 1) + { + UpdateChildCornerRadius(InternalChildren[0], CornerRadiusDict[orientation][ChildLocation.Single]); + } + else + { + UpdateChildCornerRadius(InternalChildren[0], CornerRadiusDict[orientation][ChildLocation.First]); + + var childMargin = orientation == Orientation.Horizontal + ? new Thickness(-1, 0, 0, 0) + : new Thickness(0, -1, 0, 0); + + for (var childIndex = 1; childIndex < childrenCount; childIndex++) + { + var child = InternalChildren[childIndex]; + child.SetCurrentValue(MarginProperty, childMargin); + UpdateChildCornerRadius(child, CornerRadiusDict[orientation][ChildLocation.Middle]); + } + + var lastChild = InternalChildren[childrenCount - 1]; + lastChild.SetCurrentValue(MarginProperty, childMargin); + UpdateChildCornerRadius(lastChild, CornerRadiusDict[orientation][ChildLocation.Last]); + } + } + + private static void UpdateChildCornerRadius(DependencyObject child, CornerRadius cornerRadius) + { + if (child is Border border) + { + border.SetCurrentValue(Border.CornerRadiusProperty, cornerRadius); + } + else + { + BorderElement.SetCornerRadius(child, cornerRadius); + } + } + + private void ElementAdded_LostFocus(object sender, RoutedEventArgs e) + { + if (sender is UIElement element) + { + SetZIndex(element, 0); + } + } + + private void ElementAdded_GotFocus(object sender, RoutedEventArgs e) + { + if (sender is UIElement element) + { + SetZIndex(element, int.MaxValue); + } + } + + private enum ChildLocation + { + Single, + First, + Middle, + Last + } + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 44470805..16c7f6ea 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -49,6 +49,7 @@ + diff --git a/src/Shared/HandyControl_Shared/Themes/Theme.xaml b/src/Shared/HandyControl_Shared/Themes/Theme.xaml index 2265ea6d..62dedca3 100644 --- a/src/Shared/HandyControl_Shared/Themes/Theme.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Theme.xaml @@ -2135,8 +2135,8 @@ - - + + @@ -2203,8 +2203,8 @@ - - + +