【问题标题】:Justifying objects correctly within wrappanel when objects resize调整对象大小时在包装面板中正确对齐对象
【发布时间】:2014-12-22 12:22:14
【问题描述】:

很难用几句话来描述我的问题!
这就是我想要达到的目标。

对象 #1 通常会填满其父对象的宽度。
它可以被最小化到原来宽度的一小部分,当这种情况发生时,它在其父级中右对齐。对象 #2 应该会自动向上滑动以填补空白,并且是左对齐..

我尝试了各种堆栈面板、包装面板和停靠面板 - 但无法弄清楚布局问题。

有没有一种方法可以允许这种行为,而无需在代码隐藏中进行大量丑陋的数学运算?

【问题讨论】:

  • 调整 #1 的大小,并在 WrapPanel 中重新排序这两个。当然,在计算新尺寸时需要做一些数学运算。
  • @kennyzx,你可能误解了这个问题......我不认为WrapPanel会在第一个元素是时交换两个元素的顺序最小化了……你呢?
  • #1 应该是右对齐,#2 应该是左对齐。这是我的主要问题。
  • 在此处设置 HorizontalAlignment 属性对您没有帮助。当对象被writing a custom Panel 最小化时,也许您可​​以交换项目的实际位置?或者,您可以创建一个 UserControl 将这两个对象配对并在适当的时候为您调整它们......然后将 UserControls 添加到 WrapPanel 中。

标签: c# wpf stackpanel wrappanel


【解决方案1】:

好吧,我想出了一些办法。也许不是世界上最优雅的——但它适用于我的用例。

public class CollapsingPanel : Panel
{
    /// <summary>
    /// parents are supposed to ask their children what their desired size is, given an available size
    /// </summary>
    /// <param name="availableSize"></param>
    /// <returns></returns>
    protected override Size MeasureOverride(Size availableSize)
    {
        var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(availableSize.Width, 0));
        var panelDesiredSize = new Size(availableSize.Width, 0);

        foreach (FrameworkElement child in InternalChildren)
        {
            child.Measure(availableSize);
            var childSize = child.DesiredSize;

            if (childSize.Width > availableSizeOnThisLine.Size.Width)
            {
                // this child will overflow this line: New line!
                panelDesiredSize.Height += availableSizeOnThisLine.Height;
                availableSizeOnThisLine = new Rect(new Point(0, panelDesiredSize.Height), new Size(availableSize.Width, childSize.Height));

                availableSizeOnThisLine.Width -= childSize.Width; // subtract this area/width
                availableSizeOnThisLine.Height = childSize.Height;
            }
            else
            {
                // this child will fit on this line..
                var thisChildRectangle = new Rect(childSize);
                if (child.HorizontalAlignment == HorizontalAlignment.Left)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
                    availableSizeOnThisLine.Location.Offset(childSize.Width, 0); // move to the right
                } 
                else if (child.HorizontalAlignment == HorizontalAlignment.Right)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - childSize.Width, availableSizeOnThisLine.Top);
                }

                child.Arrange(thisChildRectangle);
                availableSizeOnThisLine.Width -= childSize.Width; // subtract child's width from avbailable space
                availableSizeOnThisLine.Height = Math.Max(availableSizeOnThisLine.Height, childSize.Height);

                panelDesiredSize.Height = Math.Max(childSize.Height, panelDesiredSize.Height);
            }
        }

        return panelDesiredSize;
    }


    /// <summary>
    /// parents position their children and tell their children how much size they are actually getting
    /// </summary>
    /// <param name="finalSize"></param>
    /// <returns></returns>
    protected override Size ArrangeOverride(Size finalSize)
    {
        var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(finalSize.Width, 0));

        foreach (FrameworkElement child in InternalChildren)
        {
            var childSize = child.DesiredSize;

            if (childSize.Width > availableSizeOnThisLine.Size.Width) 
            {
                // going to wrap around
                var thisChildRectangle = new Rect(child.DesiredSize);
                availableSizeOnThisLine = new Rect(new Point(0, availableSizeOnThisLine.Height), new Size(finalSize.Width, childSize.Height));

                if (child.HorizontalAlignment == HorizontalAlignment.Right)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top);
                }
                else if (child.HorizontalAlignment == HorizontalAlignment.Left)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
                }

                child.Arrange(thisChildRectangle);
            }
            else
            {
                // put on this line
                var thisChildRectangle = new Rect(child.DesiredSize);
                if (child.HorizontalAlignment == HorizontalAlignment.Right)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top);
                }
                else if (child.HorizontalAlignment == HorizontalAlignment.Left)
                {
                    thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
                }

                child.Arrange(thisChildRectangle);
                availableSizeOnThisLine.Width -= thisChildRectangle.Width; // subtract child's width from avbailable space
            }
            availableSizeOnThisLine.Height = Math.Max(childSize.Height, availableSizeOnThisLine.Height);
        }

        return finalSize;
    }

【讨论】:

    猜你喜欢
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多