简体   繁体   中英

GridView with FlowLayout for Windows Store Apps

在此处输入图片说明

How to make a GridView like this in Foursquare app? I mean each GridViewItem in different size with respect to lenght of inner text.

Found the name FlowLayout while searching, which is the name of a third party android library. Making this functionality possible.

I tried DataTemplateSelector but this is not possible by using that. I would need tons of templates according to the lenght of text.

I did the same design as the foursquare one with a RichTextBlock because it handles the wrapping itself and each item can have it's own size.

All the details are up here http://depblog.weblogs.us/2015/02/18/how-to-add-a-tag-list-into-winrt-universal-apps/

Shawn Kendrot did the same but he used a custom control derived from Panel with a MeasureOverride to set the difference in size.

All those details are up here http://visuallylocated.com/post/2015/02/20/Creating-a-WrapPanel-for-your-Windows-Runtime-apps.aspx

Somehow I don't feel comfortable using a RichTextBox. The idea is to use a custom WrapPanel .

public class WrapPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        // Just take up all of the width
        Size finalSize = new Size { Width = availableSize.Width };
        double x = 0;
        double rowHeight = 0d;
        foreach (var child in Children)
        {
            // Tell the child control to determine the size needed
            child.Measure(availableSize);

            x += child.DesiredSize.Width;
            if (x > availableSize.Width)
            {
                // this item will start the next row
                x = child.DesiredSize.Width;

                // adjust the height of the panel
                finalSize.Height += rowHeight;
                rowHeight = child.DesiredSize.Height;
            }
            else
            {
                // Get the tallest item
                rowHeight = Math.Max(child.DesiredSize.Height, rowHeight);
            }
        }

        // Add the final height
        finalSize.Height += rowHeight;
        return finalSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Rect finalRect = new Rect(0, 0, finalSize.Width, finalSize.Height);

        double rowHeight = 0;
        foreach (var child in Children)
        {
            if ((child.DesiredSize.Width + finalRect.X) > finalSize.Width)
            {
                // next row!
                finalRect.X = 0;
                finalRect.Y += rowHeight;
                rowHeight = 0;
            }
            // Place the item
            child.Arrange(new Rect(finalRect.X, finalRect.Y, child.DesiredSize.Width, child.DesiredSize.Height));

            // adjust the location for the next items
            finalRect.X += child.DesiredSize.Width;
            rowHeight = Math.Max(child.DesiredSize.Height, rowHeight);
        }
        return finalSize;
    }

}

Using the WrapPanel you could define a ItemsPanelTemplate .

<ItemsPanelTemplate x:Key="HorizontalItemsPanel">
    <controls:WrapPanel />
</ItemsPanelTemplate>

Then the ItemsPanelTemplate can be used in either a ListView , ItemsControl or GridView .

<ListView Name="LocationItemsControl" ItemsPanel="{StaticResource HorizontalItemsPanel}"/>

You could reference a step by step tutorial here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM