模拟Windows 8开始菜单平铺布局引擎

时间:2012-07-10 05:35:23

标签: c# wpf wpf-controls microsoft-metro

那么那里的任何人都知道完全模拟Windows 8开始菜单平铺布局引擎的示例代码或控件?

它应该支持混合的Square和Rectangle Tiles,并正确地重新打包矩形块上方或下方的方块。

注意:如果ALL TILES为Square,则WrapPanel有效。但是一旦你混合了占地2平方的空间的瓷砖,布局就会中断,并且与Windows 8开始菜单不一致

我期待扩展WPF Panel的代码。


免责声明:是的我已在互联网上搜索过,我发现的最接近的是CodeProject示例,但只有在所有磁贴都是相同大小的方块时才有效。

2 个答案:

答案 0 :(得分:15)

我环顾四周,找不到任何可以做我想做的事情。我知道要获得这种行为,我们需要某种自定义面板对象,所以我开始创建一个...

归结起来的是,瓷砖需要垂直排列,双宽瓷砖在该列中占据整行,而正常宽度的瓷砖需要配对。当它到达容器的底部时,它需要创建一个新列并遵循相同的模式。

这是我的实施:

    public class MetroTilePanel : Panel
{
    protected override Size ArrangeOverride(System.Windows.Size finalSize)
    {
        double x = 0, y = 0, colWidth = 0, rowHeight = 0;
        int col = 0;
        colWidth = Children.Cast<UIElement>().Select(c => c.DesiredSize.Width).Max();

        foreach (UIElement child in Children)
        {
            rowHeight = Math.Max(rowHeight, child.DesiredSize.Height);

            if (x + child.DesiredSize.Width > (colWidth * (col + 1)))
            {
                // New row
                y += rowHeight;
                x = (colWidth * (col));
                rowHeight = child.DesiredSize.Height;
            }

            if (y + rowHeight > finalSize.Height)
            {
                // New column
                col++;
                x = (colWidth * (col));
                y = 0;
            }

            child.Arrange(new Rect(x, y, child.DesiredSize.Width, child.DesiredSize.Height));
            x += child.DesiredSize.Width;
        }
        return finalSize;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        double x = 0, y = 0, colWidth = 0;

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

            if (x + child.DesiredSize.Height > availableSize.Height)
            {
                x += colWidth;
                y = 0;
                colWidth = 0;
            }

            y += child.DesiredSize.Height;
            if (child.DesiredSize.Width > colWidth)
            {
                colWidth = child.DesiredSize.Width;
            }
        }
        x += colWidth;

        var resultSize = new Size();

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

        return resultSize;
    }
}

操作中的控件的屏幕截图: enter image description here

免责声明:

  • MeasureOverride只能偶然使用,并且设置不正确。
  • 如果你想要漂亮的MetroTile布局,那么坚持统一的尺寸,即100x100和200x100
  • 我还没有对它进行全面测试,但我会将它实现到我的假地铁应用程序中,所以如果你想看到未来的任何变化,那就大声说。
  • 如果您想要正确的GridView平铺行为,那么我们必须创建一个全新的控件(以支持拖动项目等)。

我希望这会有所帮助。

答案 1 :(得分:0)

这是我为我的项目评估的两个不同的库,用于在WPF中创建类似于Windows 8的Windows 8:

  1. Telerik RadTileList(付费)
  2. mahapps.metro(开源)