Ответ 1
Я огляделся и не мог найти ничего, что бы мы хотели. Я знал, что для такого поведения нам понадобится какой-то пользовательский объект панели, поэтому я решил создать один...
С чем это сводится, нужно, чтобы плитки располагались вертикально, причем плитки с двойной шириной занимали целую строку в этом столбце, а плитки нормальной ширины - для сопряжения. Когда он достигает нижней части контейнера, ему необходимо создать новый столбец и следовать той же схеме.
Здесь моя реализация:
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;
}
}
Снимок экрана управления в действии:
Отказ от ответственности:
- Функция MeasureOverride работает только случайно и неправильно настроена.
- Если вы хотите красивую планировку MetroTile, придерживайтесь одинаковых размеров i.e 100x100 и 200x100
- Я не тестировал его полностью, но я буду внедрять его в свое приложение fake-Metro, поэтому, если вы хотите увидеть какие-либо будущие изменения, просто кричите.
- Если вы хотите правильное поведение Tid GridView, нам нужно будет создать новый элемент управления (для поддержки перетаскивания элементов вокруг и т.д.).
Надеюсь, это поможет.