我们如何为WrapPanel设置换行点?

3
我有一个ItemsControl,希望数据可以分成两列。当用户缩小到比第二列更小的宽度时,第二列的项必须换行到第一列中。类似于UniformGrid但具有换行功能。
我已经成功使用WrapPanel来实现此目的。但是,我被迫操纵和硬编码WrapPanel的ItemWidth和MaxWidth以实现两列和换行。这不是一个好习惯。
有没有办法设置最大列数或换言之,允许我们决定WrapPanel何时开始换行?
在互联网上浏览一些资料后发现,Windows 8 Metro中的WrapGrid具有此property。是否有人在WPF中实现过这个功能?

我认为这就是WrapPanel的工作方式...绘制每个项目,直到下一个项目无法适应为止,然后换行到新行。您应该使用ItemWidthWrapPanel.Width(或MaxWidth)来告诉WrapPanel何时换行。 - Rachel
1个回答

4

在codeproject.com网站上有一篇UniformWrapPanel文章,我对其进行了修改以确保wrap panel中的项具有统一的宽度并适应窗口宽度。您可以轻松地修改此代码以设置最大列数。请尝试更改附近的代码。

var itemsPerRow = (int) (totalWidth/ItemWidth);

为了指定最大列数,可以使用以下代码:

这是代码:

public enum ItemSize
{
    None,
    Uniform,
    UniformStretchToFit
}

public class UniformWrapPanel : WrapPanel
{
    public static readonly DependencyProperty ItemSizeProperty =
        DependencyProperty.Register(
            "ItemSize", 
            typeof (ItemSize), 
            typeof (UniformWrapPanel), 
            new FrameworkPropertyMetadata(
                default(ItemSize),
                FrameworkPropertyMetadataOptions.AffectsMeasure,
                ItemSizeChanged));

    private static void ItemSizeChanged(
        DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var uniformWrapPanel = sender as UniformWrapPanel;
        if (uniformWrapPanel != null)
        {
            if (uniformWrapPanel.Orientation == Orientation.Horizontal)
            {
                uniformWrapPanel.ItemWidth = double.NaN;
            }
            else
            {
                uniformWrapPanel.ItemHeight = double.NaN;
            }
        }
    }

    public ItemSize ItemSize
    {
        get { return (ItemSize) GetValue(ItemSizeProperty); }
        set { SetValue(ItemSizeProperty, value); }
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        var mode = ItemSize;

        if (Children.Count > 0 && mode != ItemSize.None)
        {
            bool stretchToFit = mode == ItemSize.UniformStretchToFit;

            if (Orientation == Orientation.Horizontal)
            {
                double totalWidth = availableSize.Width;

                ItemWidth = 0.0;
                foreach (UIElement el in Children)
                {
                    el.Measure(availableSize);
                    Size next = el.DesiredSize;
                    if (!(Double.IsInfinity(next.Width) || Double.IsNaN(next.Width)))
                    {
                        ItemWidth = Math.Max(next.Width, ItemWidth);
                    }
                }

                if (stretchToFit)
                {
                    if (!double.IsNaN(ItemWidth) && !double.IsInfinity(ItemWidth) && ItemWidth > 0)
                    {
                        var itemsPerRow = (int) (totalWidth/ItemWidth);
                        if (itemsPerRow > 0)
                        {
                            ItemWidth = totalWidth/itemsPerRow;
                        }
                    }
                }
            }
            else
            {
                double totalHeight = availableSize.Height;

                ItemHeight = 0.0;
                foreach (UIElement el in Children)
                {
                    el.Measure(availableSize);
                    Size next = el.DesiredSize;
                    if (!(Double.IsInfinity(next.Height) || Double.IsNaN(next.Height)))
                    {
                        ItemHeight = Math.Max(next.Height, ItemHeight);
                    }
                }

                if (stretchToFit)
                {
                    if (!double.IsNaN(ItemHeight) && !double.IsInfinity(ItemHeight) && ItemHeight > 0)
                    {
                        var itemsPerColumn = (int) (totalHeight/ItemHeight);
                        if (itemsPerColumn > 0)
                        {
                            ItemHeight = totalHeight/itemsPerColumn;
                        }
                    }
                }
            }
        }

        return base.MeasureOverride(availableSize);
    }
}

太好了!感谢Phil。我成功地根据我的要求进行了定制。顺便问一下,在使用WrapPanel时是否存在性能问题? - Gordon Geek-O
我无法确定性能。大约30-40个项目似乎可以正常工作。你需要自己试一下。 - Phil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接