diff --git a/README.md b/README.md index c2ae3353..62aca62e 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,10 @@ Step 4:enjoy coding ## Latest examples +### RelativePanel + +![RelativePanel](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/RelativePanel.png) + ### Drawer ![Drawer](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/Drawer.gif) @@ -107,12 +111,12 @@ Step 4:enjoy coding ![GeometryAnimation](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/GeometryAnimation.gif) +## History publication + ### SplitButton ![SplitButton](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/SplitButton.png) -## History publication - ### FloatingBlock ![FloatingBlock](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/FloatingBlock.gif) diff --git a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj index 36a197df..bd93971a 100644 --- a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj +++ b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj @@ -448,6 +448,9 @@ Resources\Img\LeftMainContent\View_Portrait_16x.png + + Resources\Img\LeftMainContent\TransformRelative_16x.png + diff --git a/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj b/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj index e5a658ad..65e72972 100644 --- a/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj +++ b/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj @@ -430,6 +430,9 @@ TextTemplatingFileGenerator MessageToken.cs + + Resources\Img\LeftMainContent\TransformRelative_16x.png + Resources\Img\LeftMainContent\View_Portrait_16x.png diff --git a/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj b/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj index 1fa83a40..8a6b97f4 100644 --- a/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj +++ b/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj @@ -496,6 +496,9 @@ TextTemplatingFileGenerator MessageToken.cs + + Resources\Img\LeftMainContent\TransformRelative_16x.png + Resources\Img\LeftMainContent\View_Portrait_16x.png diff --git a/src/Shared/HandyControlDemo_Shared/Data/DemoInfo.json b/src/Shared/HandyControlDemo_Shared/Data/DemoInfo.json index 6c5f4f76..92439c37 100644 --- a/src/Shared/HandyControlDemo_Shared/Data/DemoInfo.json +++ b/src/Shared/HandyControlDemo_Shared/Data/DemoInfo.json @@ -40,7 +40,7 @@ [ "Gravatar", "GravatarDemoCtl", "User_16x", "" ], [ "Badge", "BadgeDemoCtl", "DotLarge_16x", "" ], [ "GotoTop", "GotoTopDemoCtl", "GoToTop_16x", "" ], - [ "SplitButton", "SplitButtonDemoCtl", "SplitButton_16x", "1" ], + [ "SplitButton", "SplitButtonDemoCtl", "SplitButton_16x", "" ], [ "ButtonGroup", "ButtonGroupDemoCtl", "ButtonGroup_16x", "" ], [ "ProgressButton", "ProgressButtonDemoCtl", "ProgressButton_16x", "" ], [ "ChatBubble", "ChatBubbleDemoCtl", "Bubble_16xLG", "" ], @@ -68,6 +68,7 @@ [ "Divider", "DividerDemoCtl", "DottedSplitter_16x", "1" ], [ "CirclePanel", "CirclePanelDemoCtl", "ColorWheel_16x", "" ], [ "Grid", "GridDemoCtl", "GridPane_16x", "" ], + [ "RelativePanel", "RelativePanelDemoCtl", "TransformRelative_16x", "1" ], [ "WaterfallPanel", "WaterfallPanelDemoCtl", "Panel_16x", "" ], [ "HoneycombPanel", "HoneycombPanelDemoCtl", "PolygonHexagon_16x", "" ], [ "TransitioningContentControl", "TransitioningContentControlDemoCtl", "TransitioningContentControl_16x", "" ], diff --git a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems index 6d09742c..4fe569a5 100644 --- a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems +++ b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems @@ -182,6 +182,9 @@ RateDemoCtl.xaml + + RelativePanelDemoCtl.xaml + RunningBlockDemoCtl.xaml @@ -640,6 +643,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/TransformRelative_16x.png b/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/TransformRelative_16x.png new file mode 100644 index 00000000..bf04a7a9 Binary files /dev/null and b/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/TransformRelative_16x.png differ diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml new file mode 100644 index 00000000..87ca8eca --- /dev/null +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml.cs b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml.cs new file mode 100644 index 00000000..747c9b57 --- /dev/null +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/RelativePanelDemoCtl.xaml.cs @@ -0,0 +1,10 @@ +namespace HandyControlDemo.UserControl +{ + public partial class RelativePanelDemoCtl + { + public RelativePanelDemoCtl() + { + InitializeComponent(); + } + } +} diff --git a/src/Shared/HandyControl_Shared/Controls/Grid/Col.cs b/src/Shared/HandyControl_Shared/Controls/Panel/Grid/Col.cs similarity index 100% rename from src/Shared/HandyControl_Shared/Controls/Grid/Col.cs rename to src/Shared/HandyControl_Shared/Controls/Panel/Grid/Col.cs diff --git a/src/Shared/HandyControl_Shared/Controls/Grid/Row.cs b/src/Shared/HandyControl_Shared/Controls/Panel/Grid/Row.cs similarity index 100% rename from src/Shared/HandyControl_Shared/Controls/Grid/Row.cs rename to src/Shared/HandyControl_Shared/Controls/Panel/Grid/Row.cs diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/RelativePanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/RelativePanel.cs new file mode 100644 index 00000000..f2705d0e --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Panel/RelativePanel.cs @@ -0,0 +1,501 @@ +//reference doc : https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.RelativePanel + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using HandyControl.Data; + +namespace HandyControl.Controls +{ + public class RelativePanel : Panel + { + private readonly Graph _childGraph; + + public RelativePanel() => _childGraph = new Graph(); + + #region 容器对齐方式 + + public static readonly DependencyProperty AlignLeftWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignLeftWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignLeftWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignLeftWithPanelProperty, value); + + public static bool GetAlignLeftWithPanel(DependencyObject element) + => (bool) element.GetValue(AlignLeftWithPanelProperty); + + public static readonly DependencyProperty AlignTopWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignTopWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignTopWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignTopWithPanelProperty, value); + + public static bool GetAlignTopWithPanel(DependencyObject element) + => (bool) element.GetValue(AlignTopWithPanelProperty); + + public static readonly DependencyProperty AlignRightWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignRightWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignRightWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignRightWithPanelProperty, value); + + public static bool GetAlignRightWithPanel(DependencyObject element) + => (bool) element.GetValue(AlignRightWithPanelProperty); + + public static readonly DependencyProperty AlignBottomWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignBottomWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignBottomWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignBottomWithPanelProperty, value); + + public static bool GetAlignBottomWithPanel(DependencyObject element) + => (bool) element.GetValue(AlignBottomWithPanelProperty); + + #endregion + + #region 元素间对齐方式 + + public static readonly DependencyProperty AlignLeftWithProperty = DependencyProperty.RegisterAttached( + "AlignLeftWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignLeftWith(DependencyObject element, UIElement value) + => element.SetValue(AlignLeftWithProperty, value); + + public static UIElement GetAlignLeftWith(DependencyObject element) + => (UIElement) element.GetValue(AlignLeftWithProperty); + + public static readonly DependencyProperty AlignTopWithProperty = DependencyProperty.RegisterAttached( + "AlignTopWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignTopWith(DependencyObject element, UIElement value) + => element.SetValue(AlignTopWithProperty, value); + + public static UIElement GetAlignTopWith(DependencyObject element) + => (UIElement) element.GetValue(AlignTopWithProperty); + + public static readonly DependencyProperty AlignRightWithProperty = DependencyProperty.RegisterAttached( + "AlignRightWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignRightWith(DependencyObject element, UIElement value) + => element.SetValue(AlignRightWithProperty, value); + + public static UIElement GetAlignRightWith(DependencyObject element) + => (UIElement) element.GetValue(AlignRightWithProperty); + + public static readonly DependencyProperty AlignBottomWithProperty = DependencyProperty.RegisterAttached( + "AlignBottomWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignBottomWith(DependencyObject element, UIElement value) + => element.SetValue(AlignBottomWithProperty, value); + + public static UIElement GetAlignBottomWith(DependencyObject element) + => (UIElement) element.GetValue(AlignBottomWithProperty); + + #endregion + + #region 元素间位置关系 + + public static readonly DependencyProperty LeftOfProperty = DependencyProperty.RegisterAttached( + "LeftOf", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetLeftOf(DependencyObject element, UIElement value) + => element.SetValue(LeftOfProperty, value); + + public static UIElement GetLeftOf(DependencyObject element) + => (UIElement)element.GetValue(LeftOfProperty); + + public static readonly DependencyProperty AboveProperty = DependencyProperty.RegisterAttached( + "Above", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAbove(DependencyObject element, UIElement value) + => element.SetValue(AboveProperty, value); + + public static UIElement GetAbove(DependencyObject element) + => (UIElement)element.GetValue(AboveProperty); + + public static readonly DependencyProperty RightOfProperty = DependencyProperty.RegisterAttached( + "RightOf", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetRightOf(DependencyObject element, UIElement value) + => element.SetValue(RightOfProperty, value); + + public static UIElement GetRightOf(DependencyObject element) + => (UIElement)element.GetValue(RightOfProperty); + + public static readonly DependencyProperty BelowProperty = DependencyProperty.RegisterAttached( + "Below", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetBelow(DependencyObject element, UIElement value) + => element.SetValue(BelowProperty, value); + + public static UIElement GetBelow(DependencyObject element) + => (UIElement) element.GetValue(BelowProperty); + + #endregion + + #region 居中对齐方式 + + public static readonly DependencyProperty AlignHorizontalCenterWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignHorizontalCenterWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignHorizontalCenterWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignHorizontalCenterWithPanelProperty, value); + + public static bool GetAlignHorizontalCenterWithPanel(DependencyObject element) + => (bool)element.GetValue(AlignHorizontalCenterWithPanelProperty); + + public static readonly DependencyProperty AlignVerticalCenterWithPanelProperty = DependencyProperty.RegisterAttached( + "AlignVerticalCenterWithPanel", typeof(bool), typeof(RelativePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignVerticalCenterWithPanel(DependencyObject element, bool value) + => element.SetValue(AlignVerticalCenterWithPanelProperty, value); + + public static bool GetAlignVerticalCenterWithPanel(DependencyObject element) + => (bool)element.GetValue(AlignVerticalCenterWithPanelProperty); + + public static readonly DependencyProperty AlignHorizontalCenterWithProperty = DependencyProperty.RegisterAttached( + "AlignHorizontalCenterWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignHorizontalCenterWith(DependencyObject element, UIElement value) + => element.SetValue(AlignHorizontalCenterWithProperty, value); + + public static UIElement GetAlignHorizontalCenterWith(DependencyObject element) + => (UIElement)element.GetValue(AlignHorizontalCenterWithProperty); + + public static readonly DependencyProperty AlignVerticalCenterWithProperty = DependencyProperty.RegisterAttached( + "AlignVerticalCenterWith", typeof(UIElement), typeof(RelativePanel), new FrameworkPropertyMetadata(default(UIElement), FrameworkPropertyMetadataOptions.AffectsRender)); + + public static void SetAlignVerticalCenterWith(DependencyObject element, UIElement value) + => element.SetValue(AlignVerticalCenterWithProperty, value); + + public static UIElement GetAlignVerticalCenterWith(DependencyObject element) + => (UIElement)element.GetValue(AlignVerticalCenterWithProperty); + + #endregion + + protected override Size MeasureOverride(Size availableSize) + { + foreach (UIElement child in InternalChildren) + { + child?.Measure(availableSize); + } + + return base.MeasureOverride(availableSize); + } + + protected override Size ArrangeOverride(Size arrangeSize) + { + _childGraph.Reset(arrangeSize); + + foreach (UIElement child in InternalChildren) + { + if (child == null) continue; + + var node = _childGraph.AddNode(child); + + node.AlignLeftWithNode = _childGraph.AddLink(node, GetAlignLeftWith(child)); + node.AlignTopWithNode = _childGraph.AddLink(node, GetAlignTopWith(child)); + node.AlignRightWithNode = _childGraph.AddLink(node, GetAlignRightWith(child)); + node.AlignBottomWithNode = _childGraph.AddLink(node, GetAlignBottomWith(child)); + + node.LeftOfNode = _childGraph.AddLink(node, GetLeftOf(child)); + node.AboveNode = _childGraph.AddLink(node, GetAbove(child)); + node.RightOfNode = _childGraph.AddLink(node, GetRightOf(child)); + node.BelowNode = _childGraph.AddLink(node, GetBelow(child)); + + node.AlignHorizontalCenterWith = _childGraph.AddLink(node, GetAlignHorizontalCenterWith(child)); + node.AlignVerticalCenterWith = _childGraph.AddLink(node, GetAlignVerticalCenterWith(child)); + } + + if (_childGraph.CheckCyclic()) + { + throw new Exception("RelativePanel error: Circular dependency detected. Layout could not complete."); + } + + return arrangeSize; + } + + private class GraphNode + { + public Point Position { get; set; } + + public bool Arranged { get; set; } + + public UIElement Element { get; } + + public HashSet OutgoingNodes { get; } + + public GraphNode AlignLeftWithNode { get; set; } + + public GraphNode AlignTopWithNode { get; set; } + + public GraphNode AlignRightWithNode { get; set; } + + public GraphNode AlignBottomWithNode { get; set; } + + public GraphNode LeftOfNode { get; set; } + + public GraphNode AboveNode { get; set; } + + public GraphNode RightOfNode { get; set; } + + public GraphNode BelowNode { get; set; } + + public GraphNode AlignHorizontalCenterWith { get; set; } + + public GraphNode AlignVerticalCenterWith { get; set; } + + public GraphNode(UIElement element) + { + OutgoingNodes = new HashSet(); + Element = element; + } + } + + private class Graph + { + private readonly Dictionary _nodeDic; + + private Size _arrangeSize; + + public Graph() + { + _nodeDic = new Dictionary(); + } + + public GraphNode AddLink(GraphNode from, UIElement to) + { + if (to == null) return null; + + GraphNode nodeTo; + if (_nodeDic.ContainsKey(to)) + { + nodeTo = _nodeDic[to]; + } + else + { + nodeTo = new GraphNode(to); + _nodeDic[to] = nodeTo; + } + + from.OutgoingNodes.Add(nodeTo); + return nodeTo; + } + + public GraphNode AddNode(UIElement value) + { + if (!_nodeDic.ContainsKey(value)) + { + var node = new GraphNode(value); + _nodeDic.Add(value, node); + return node; + } + + return _nodeDic[value]; + } + + public void Reset(Size arrangeSize) + { + _arrangeSize = arrangeSize; + _nodeDic.Clear(); + } + + public bool CheckCyclic() => CheckCyclic(_nodeDic.Values, null); + + private bool CheckCyclic(IEnumerable nodes, HashSet set) + { + if (set == null) + { + set = new HashSet(); + } + + foreach (var node in nodes) + { + /* + * 该节点无任何依赖,所以从这里开始计算元素位置。 + * 因为无任何依赖,所以忽略同级元素 + */ + if (!node.Arranged && node.OutgoingNodes.Count == 0) + { + ArrangeChild(node, true); + continue; + } + + // 判断依赖元素是否全部排列完毕 + if (node.OutgoingNodes.All(item => item.Arranged)) + { + ArrangeChild(node); + continue; + } + + // 判断是否有循环 + if (!set.Add(node.Element)) return true; + + // 没有循环,且有依赖,则继续往下 + return CheckCyclic(node.OutgoingNodes, set); + } + + return false; + } + + private void ArrangeChild(GraphNode node, bool ignoneSibling = false) + { + var child = node.Element; + var childSize = child.DesiredSize; + var childPos = new Point(); + + #region 容器居中对齐 + + if (GetAlignHorizontalCenterWithPanel(child)) + { + childPos.X = (_arrangeSize.Width - childSize.Width) / 2; + } + + if (GetAlignVerticalCenterWithPanel(child)) + { + childPos.Y = (_arrangeSize.Height - childSize.Height) / 2; + } + + #endregion + + var alignLeftWithPanel = GetAlignLeftWithPanel(child); + var alignTopWithPanel = GetAlignTopWithPanel(child); + var alignRightWithPanel = GetAlignRightWithPanel(child); + var alignBottomWithPanel = GetAlignBottomWithPanel(child); + + if (!ignoneSibling) + { + #region 元素间位置 + + if (node.LeftOfNode != null) + { + childPos.X = node.LeftOfNode.Position.X - childSize.Width; + } + + if (node.AboveNode != null) + { + childPos.Y = node.AboveNode.Position.Y - childSize.Height; + } + + if (node.RightOfNode != null) + { + childPos.X = node.RightOfNode.Position.X + node.RightOfNode.Element.DesiredSize.Width; + } + + if (node.BelowNode != null) + { + childPos.Y = node.BelowNode.Position.Y + node.BelowNode.Element.DesiredSize.Height; + } + + #endregion + + #region 元素居中对齐 + + if (node.AlignHorizontalCenterWith != null) + { + childPos.X = node.AlignHorizontalCenterWith.Position.X + + (node.AlignHorizontalCenterWith.Element.DesiredSize.Width - childSize.Width) / 2; + } + + if (node.AlignVerticalCenterWith != null) + { + childPos.Y = node.AlignVerticalCenterWith.Position.Y + + (node.AlignVerticalCenterWith.Element.DesiredSize.Height - childSize.Height) / 2; + } + + #endregion + + #region 元素间对齐 + + if (node.AlignLeftWithNode != null) + { + childPos.X = node.AlignLeftWithNode.Position.X; + } + + if (node.AlignTopWithNode != null) + { + childPos.Y = node.AlignTopWithNode.Position.Y; + } + + if (node.AlignRightWithNode != null) + { + childPos.X = node.AlignRightWithNode.Element.DesiredSize.Width + node.AlignRightWithNode.Position.X - childSize.Width; + } + + if (node.AlignBottomWithNode != null) + { + childPos.Y = node.AlignBottomWithNode.Element.DesiredSize.Height + node.AlignBottomWithNode.Position.Y - childSize.Height; + } + + #endregion + } + + #region 容器对齐 + + if (alignLeftWithPanel) + { + if (node.AlignRightWithNode != null) + { + childPos.X = (node.AlignRightWithNode.Element.DesiredSize.Width + node.AlignRightWithNode.Position.X - childSize.Width) / 2; + } + else + { + childPos.X = 0; + } + } + + if (alignTopWithPanel) + { + if (node.AlignBottomWithNode != null) + { + childPos.Y = (node.AlignBottomWithNode.Element.DesiredSize.Height + node.AlignBottomWithNode.Position.Y - childSize.Height) / 2; + } + else + { + childPos.Y = 0; + } + } + + if (alignRightWithPanel) + { + if (alignLeftWithPanel) + { + childPos.X = (_arrangeSize.Width - childSize.Width) / 2; + } + else if(node.AlignLeftWithNode == null) + { + childPos.X = _arrangeSize.Width - childSize.Width; + } + else + { + childPos.X = (_arrangeSize.Width + node.AlignLeftWithNode.Position.X - childSize.Width) / 2; + } + } + + if (alignBottomWithPanel) + { + if (alignTopWithPanel) + { + childPos.Y = (_arrangeSize.Height - childSize.Height) / 2; + } + else if (node.AlignTopWithNode == null) + { + childPos.Y = _arrangeSize.Height - childSize.Height; + } + else + { + childPos.Y = (_arrangeSize.Height + node.AlignLeftWithNode.Position.Y - childSize.Height) / 2; + } + } + + #endregion + + child.Arrange(new Rect(childPos.X, childPos.Y, childSize.Width, childSize.Height)); + node.Position = childPos; + node.Arranged = true; + } + } + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 32a40820..b01bf9b2 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -35,6 +35,7 @@ + @@ -90,8 +91,8 @@ - - + + diff --git a/src/Shared/HandyControl_Shared/Tools/Converter/ColLayoutConverter.cs b/src/Shared/HandyControl_Shared/Tools/Converter/ColLayoutConverter.cs index c4bbfb88..922c7a57 100644 --- a/src/Shared/HandyControl_Shared/Tools/Converter/ColLayoutConverter.cs +++ b/src/Shared/HandyControl_Shared/Tools/Converter/ColLayoutConverter.cs @@ -55,9 +55,8 @@ namespace HandyControl.Tools.Converter if (destinationType == null) throw new ArgumentNullException(nameof(destinationType)); - if (!(value is ColLayout)) throw new ArgumentException("UnexpectedParameterType"); + if (!(value is ColLayout th)) throw new ArgumentException("UnexpectedParameterType"); - var th = (ColLayout)value; if (destinationType == typeof(string)) return ToString(th, cultureInfo); if (destinationType == typeof(InstanceDescriptor)) {