代码之家  ›  专栏  ›  技术社区  ›  Heysem Katibi

固定包裹面板wpf

  •  13
  • Heysem Katibi  · 技术社区  · 12 年前

    我正在开发wpf窗口,该窗口通过包装显示相邻项目的列表,我已经尝试过使用 WrapPanel 通过这种方式:

    <Grid>
        <ItemsControl>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
    
            <ItemsControl.Items>
                <Button Content="01" Height="30" Width="70"/>
                <Button Content="02" Height="35" Width="72"/>
                <Button Content="03" Height="20" Width="74"/>
                <Button Content="04" Height="25" Width="76"/>
                <Button Content="05" Height="18" Width="78"/>
                <Button Content="06" Height="50" Width="70"/>
                <Button Content="07" Height="40" Width="72"/>
                <Button Content="08" Height="55" Width="74"/>
                <Button Content="09" Height="45" Width="76"/>
                <Button Content="10" Height="25" Width="78"/>
                <Button Content="11" Height="20" Width="80"/>
                <Button Content="12" Height="30" Width="70"/>
                <Button Content="13" Height="45" Width="72"/>
                <Button Content="14" Height="30" Width="74"/>
                <Button Content="15" Height="20" Width="76"/>
                <Button Content="16" Height="25" Width="78"/>
                <Button Content="17" Height="35" Width="80"/>
                <Button Content="18" Height="50" Width="70"/>
                <Button Content="19" Height="55" Width="72"/>
                <Button Content="20" Height="45" Width="74"/>
                <Button Content="21" Height="20" Width="76"/>
                <Button Content="22" Height="60" Width="78"/>
                <Button Content="23" Height="20" Width="80"/>
                <Button Content="24" Height="25" Width="70"/>
                <Button Content="25" Height="30" Width="72"/>
            </ItemsControl.Items>
        </ItemsControl>
    </Grid>
    

    并且这是结果:

    enter image description here

    事实上,这个结果对我来说并不令人满意,因为如果你想象 折叠容器 作为网格(行和列),您会发现没有列,但有固定大小的行。我需要制作 WarpPanel 或者一些没有列的控件,看看这个想象中的图像:

    enter image description here

    请注意,这里没有行和列。这就是我想要做的。

    有人有办法解决这个问题吗?

    2 回复  |  直到 12 年前
        1
  •  9
  •   Clemens    12 年前

    您可以编写自己的自定义Panel类。网上有一些教程,只需谷歌“wpf自定义面板”即可。

    它可以归结为覆盖 MeasureOverride ArrangeOverride 方法。

    public class CustomPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            Size panelDesiredSize = new Size();
    
            foreach (UIElement child in InternalChildren)
            {
                child.Measure(availableSize);
    
                // Use child.DesiredSize, availableSize.Width and the positions
                // and sizes of the previous children to calculate the position of
                // the current child. Then determine the resulting Panel height.
                panelDesiredSize = ...
            }
    
            return panelDesiredSize;
        }
    
        protected override Size ArrangeOverride(Size finalSize)
        {
            foreach (UIElement child in InternalChildren)
            {
                // Arrange each child according to the position calculations
                // done in MeasureOverride
                Point position = ...
                child.Arrange(new Rect(position, child.DesiredSize));
            }
    
            return finalSize;
        }
    }
    

    更新 :以下简单的自定义面板可能或多或少可以满足您的需要。

    public class PackPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement child in InternalChildren)
            {
                child.Measure(availableSize);
            }
    
            var positions = new Point[InternalChildren.Count];
            var desiredHeight = ArrangeChildren(positions, availableSize.Width);
    
            return new Size(availableSize.Width, desiredHeight);
        }
    
        protected override Size ArrangeOverride(Size finalSize)
        {
            var positions = new Point[InternalChildren.Count];
            ArrangeChildren(positions, finalSize.Width);
    
            for (int i = 0; i < InternalChildren.Count; i++)
            {
                var child = InternalChildren[i];
                child.Arrange(new Rect(positions[i], child.DesiredSize));
            }
    
            return finalSize;
        }
    
        private double ArrangeChildren(Point[] positions, double availableWidth)
        {
            var lastRowStartIndex = -1;
            var lastRowEndIndex = 0;
            var currentWidth = 0d;
            var desiredHeight = 0d;
    
            for (int childIndex = 0; childIndex < InternalChildren.Count; childIndex++)
            {
                var child = InternalChildren[childIndex];
                var x = 0d;
                var y = 0d;
    
                if (currentWidth == 0d || currentWidth + child.DesiredSize.Width <= availableWidth)
                {
                    x = currentWidth;
                    currentWidth += child.DesiredSize.Width;
                }
                else
                {
                    currentWidth = child.DesiredSize.Width;
                    lastRowStartIndex = lastRowEndIndex;
                    lastRowEndIndex = childIndex;
                }
    
                if (lastRowStartIndex >= 0)
                {
                    int i = lastRowStartIndex;
    
                    while (i < lastRowEndIndex - 1 && positions[i + 1].X < x)
                    {
                        i++;
                    }
    
                    while (i < lastRowEndIndex && positions[i].X < x + child.DesiredSize.Width)
                    {
                        y = Math.Max(y, positions[i].Y + InternalChildren[i].DesiredSize.Height);
                        i++;
                    }
                }
    
                positions[childIndex] = new Point(x, y);
                desiredHeight = Math.Max(desiredHeight, y + child.DesiredSize.Height);
            }
    
            return desiredHeight;
        }
    }
    
        2
  •  -1
  •   YOusaFZai    12 年前

    您可以使用画布:

    或者使用网格并根据需要设置每个按钮的边距

         <Canvas >
            <Button Content="s" Width="50" Canvas.Left="17" Canvas.Top="20" />
            <Button Canvas.Left="73" Canvas.Top="32" Content="s" Width="60" Height="42" />
            <Button Canvas.Left="139" Canvas.Top="10" Content="s" Height="42" Width="60" />
         </Canvas>
    
          <Grid >
                <Button Content="01" Height="30" Width="70" Margin="20,12,414,268" />
                <Button Content="02" Height="35" Width="72" Margin="426,148,6,128" />
                <Button Content="03" Height="20" Width="74" Margin="190,122,240,170" />
                <Button Content="04" Height="25" Width="76" Margin="386,26,40,260" />
                <Button Content="05" Height="18" Width="78" Margin="376,202,48,92" />
                <Button Content="06" Height="50" Width="70" Margin="385,64,48,196" />
                <Button Content="07" Height="40" Width="72" Margin="162,202,269,68" />
                <Button Content="08" Height="55" Width="74" Margin="20,154,408,102" />
                <Button Content="09" Height="45" Width="76" Margin="21,95,406,171" />
                <Button Content="10" Height="25" Width="78" Margin="44,47,382,239" />
                <Button Content="11" Height="20" Width="80" Margin="386,120,38,170" />
                <Button Content="12" Height="30" Width="70" Margin="95,13,338,268" />
                <Button Content="13" Height="45" Width="72" Margin="290,6,140,260" />
                <Button Content="14" Height="30" Width="74" Margin="210,38,220,244" />
                <Button Content="15" Height="20" Width="76" Margin="128,48,299,242" />
                <Button Content="16" Height="25" Width="78" Margin="265,189,160,97" />
                <Button Content="17" Height="35" Width="80" Margin="176,154,246,122" />
                <Button Content="18" Height="50" Width="70" Margin="100,146,333,116" />
                <Button Content="19" Height="55" Width="72" Margin="270,121,160,135" />
                <Button Content="20" Height="45" Width="74" Margin="348,148,81,118" />
                <Button Content="21" Height="20" Width="76" Margin="94,78,332,212" />
                <Button Content="22" Height="60" Width="78" Margin="270,60,155,192" />
                <Button Content="23" Height="20" Width="80" Margin="176,74,247,216" />
                <Button Content="24" Height="25" Width="70" Margin="194,95,238,191" />
                <Button Content="25" Height="30" Width="72" Margin="117,104,314,177" />
    
        </Grid>