找到给定大小

时间:2016-04-16 07:06:07

标签: c# wpf algorithm layout

我有一个WPF自定义面板,其中我想要布局几个元素(在我的情况下为12,但理想情况下我想找到适合所有的算法)都具有相同的最小宽度/高度。布局是一个网格,但我可以选择我想要的列/行数。

我想找到一种方法来决定我创建的列数和行数,具体取决于窗口的比例。

如果子元素的比例为1/1,则会更容易;我只需要计算可能布局的比例(承认我有12个子元素:12 / 1,6 / 2,4 / 3,3 / 4,2 / 6,1 / 12)并检查哪一个是更接近面板宽度/高度比。

但在我的实际案例中,我可以设置两倍于宽的子项,所以我对如何计算它有点迷失?我想我需要采取他们的“理想大小”,然后在两者之间做一些数学计算,但我不知道如何。

谢谢!

1 个答案:

答案 0 :(得分:0)

经过一些实验和单元测试后,我想我找到了解决方案。事实上,我不需要宽度/高度,只需要它们的比例,对于元素也是如此。

我有以下表示布局的类:

public class Layout : IEquatable<Layout>
{
    public int RowCount { get; }
    public int ColumnCount { get;  }
    public double Ratio { get; }

    public Layout(int rowCount, int columnCount)
    {
        RowCount = rowCount;
        ColumnCount = columnCount;
        Ratio = (float)rowCount/columnCount;
    }
}

我已完成以下工作以获得最佳布局:

public class LayoutAdapter
{
    public Layout ComputeBestGridLayout(int elementsCount, double elementRatio, double panelRatio)
    {
        IEnumerable<Layout> possibleLayouts = GetPossibleLayouts(elementsCount);
        return FindBestLayouts(possibleLayouts, elementRatio, panelRatio);
    }

    private IEnumerable<Layout> GetPossibleLayouts(int elementCounts)
    {
        //TODO Increment "elementsCounts", because maybe with some hole we will have a better match for the ratio
        List<Layout> acceptedResults =new List<Layout>();
        for (int i1 = 0; i1 <= elementCounts; i1++)
        {
            double rest2 = elementCounts%((double) i1);
            if (rest2 == 0)
            {
                int i2 = elementCounts/i1;
                acceptedResults.Add(new Layout(i1,i2));
            }
        }
        return acceptedResults;
    }


    private Layout FindBestLayouts(IEnumerable<Layout> possibleLayouts, double elementRatio, double panelRatio)
    {
        Layout closestLayout = null;
        double minDiff=Double.MaxValue;


        foreach (Layout possibleLayout in possibleLayouts)
        {
            double currentDiff = Math.Abs((panelRatio/ elementRatio) - possibleLayout.Ratio);
            if (currentDiff < minDiff)
            {
                minDiff = currentDiff;
                closestLayout = possibleLayout;
            }
        }
        return closestLayout;
    }

}