WPF自定义面板缩放以适合窗口

时间:2011-04-07 13:34:21

标签: c# wpf

我有一个WPF自定义面板,可根据我的要求将其子元素排列成螺旋形状。我遇到的问题是在调整窗口大小时缩放项目 - 此时它不会缩放。有人能提供解决方案吗?谢谢 - 本

自定义面板

public class TagPanel : Panel
{
    protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
    {
        Size resultSize = new Size(0, 0);

        foreach (UIElement child in Children)
        {
            child.Measure(availableSize);

            resultSize.Width = Math.Max(resultSize.Width, child.DesiredSize.Width);
            resultSize.Height = Math.Max(resultSize.Height, child.DesiredSize.Height);

        }

        resultSize.Width = double.IsPositiveInfinity(availableSize.Width) ?
            resultSize.Width : availableSize.Width;

        resultSize.Height = double.IsPositiveInfinity(availableSize.Height) ?
            resultSize.Height : availableSize.Height;

        return resultSize;

    }

    protected class InnerPos
    {
        public UIElement Element { get; set; }
        public Size Size { get; set; }
    }

    private Point GetSpiralPosition(double theta, Size windowSize)
    {
        double a = 5.0;
        double n = 1.0;

        double r = a * (Math.Pow(theta, 1.0 / n));

        double x = r * Math.Cos(theta);
        double y = r * Math.Sin(theta);

        x += windowSize.Width / 2.0;
        y += windowSize.Height / 2.0;

        return new Point(x,y);

    }

    private Rect CreateRectangleCenteredAtPoint(Point pt, double width, double height)
    {
        return new Rect(new Point(pt.X - (width / 2.0), pt.Y - (height / 2.0)),
            new Size(width, height));

    }

    protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
    {
        //double startPos = 0.0;

        List<InnerPos> positions = new List<InnerPos>();

        foreach (UIElement ch in Children)
        {
            // If this is the first time
            // we've seen this child, add our transforms

            //if (ch.RenderTransform as TransformGroup == null)
            //{
            //    ch.RenderTransformOrigin = new Point(0, 0.5);
            //    TransformGroup group = new TransformGroup();
            //    ch.RenderTransform = group;
            //    group.Children.Add(new ScaleTransform());
            //    group.Children.Add(new TranslateTransform());

            //}

            positions.Add(new InnerPos()
            {
                Element = ch,
                Size = ch.DesiredSize

            });
        }

        //double currentTopMax
        List<Rect> alreadyUsedPositions = new List<Rect>();

        foreach (InnerPos child in positions.OrderByDescending(i => i.Size.Width))
        {

            for (double theta = 0.0; theta < 100.0; theta += 0.1)
            {
                Point spiralPos = GetSpiralPosition(theta, finalSize);
                Rect centeredRect = CreateRectangleCenteredAtPoint(spiralPos,
                    child.Element.DesiredSize.Width,
                    child.Element.DesiredSize.Height);

                bool posIsOk = true;
                foreach (Rect existing in alreadyUsedPositions)
                {
                    bool positionClashes = existing.IntersectsWith(centeredRect);
                    if (positionClashes == true)
                    {
                        posIsOk = false;
                        break;
                    }
                }

                if (posIsOk)
                {
                    alreadyUsedPositions.Add(centeredRect);

                    child.Element.Arrange(centeredRect);
                    break;
                }


            }

        }

        return finalSize;

    }
}

1 个答案:

答案 0 :(得分:0)

HorizontalAlignment的{​​{1}}和VerticalAlignment设置为PanelStretch / Width设置为自动(Height })?

看起来你正在将double.NaN传递给finalSize,这是所有真正工作发生的功能。没有看到这个函数的代码,很难说更多,但我假设你正在GetSpiralPosition()正确计算。

在调整窗口大小时,您是否已调试以查看是否使用更新的大小调用finalSize?有两种方法可以测试它:首先,设置跟踪点而不是断点。将Arrange转储到输出窗口,并在调整窗口大小时查看它是否发生变化。其次,在窗口中添加一个处理程序finalSize。在处理程序中放置一个断点。当命中断点时,在自定义面板的arrange方法中放置一个断点,然后运行。

相关问题