Here - отличный блог-блог о том, как создать WrapPanel на основе ваших требований.
Я создал TagsPanel
, основанный на этом блоге, чтобы использовать его в одном из моих приложений. Ключ должен переходить к элементам и получать фактический размер и устанавливать его на основе доступной ширины панели. Смотри ниже.
public class TagsPanel : 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;
}
}
и использовать его в GridView
, как показано ниже.
<GridView ItemsSource="{Binding tags}" >
<GridView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding ''}" Margin="5"/>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<local:TagsPanel/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Как насчет использования стекольной панели с вертикальной ориентацией и внутри нее stackpanel с горизонтальной ориентацией, содержащей максимум 3 кнопки? – Pratyay
@Pratyay, ну, что можно сделать, но если я добавлю 3 кнопки в каждую горизонтальную стеклянную панель, это может привести к слишком длинным строкам, если все 3 кнопки имеют более длинный контент. Конечно, можно добавить горизонтальную полосу прокрутки, но было бы неплохо избежать горизонтальной полосы прокрутки в моем случае. Любое другое лучшее решение? – praveenDM
Ну, легкий выход из проблемы с длинными строками будет определять MaxWidth для кнопок, которые будут составлять 1/3 от ширины стека (и учитывая разницу между кнопками, которые добавляет панель стека по умолчанию) .., но это приведет к обрыву содержимого (или текст) внутри кнопки. Также учитывая, что вы создаете приложение UWP, оно должно иметь возможность масштабировать любое разрешение экрана без проблем, вы должны переключиться на VariableSizedWrapGrid или проверить размер экрана на событии GridSizeChanged и соответствующим образом заполнить его (что будет иметь серьезные если проблемы не выполняются правильно). – Pratyay