I have an ItemsControl and I want the data to be entered into two columns. When the User resizes to a width lesser than the second column, the items of the second column must wrap into the first column. Something like a UniformGrid but with wrapping.
我有一个ItemsControl,我希望将数据输入两列。当用户调整宽度小于第二列的宽度时,第二列的项必须包装到第一列。像UniformGrid的东西,但有包装。
I have managed to use a WrapPanel to do this. But I am forced to manipulate and hard code the ItemWidth and MaxWidth of the WrapPanel to achieve the two columns thing and the wrapping. This is not a good practice.
我设法使用WrapPanel来做到这一点。但我*操纵并硬编码WrapPanel的ItemWidth和MaxWidth来实现两列事物和包装。这不是一个好习惯。
Is there anyway to set the Maximum no of columns or in other words allowing us to decide at what point the WrapPanel should start wrapping?
无论如何设置最大列数或换句话说允许我们决定WrapPanel应该在什么时候开始包装?
Some browsing on the internet revealed that the WrapGrid in Windows 8 Metro has this property. Does anyone have this implementation in WPF?
一些在互联网上浏览的消息显示,Windows 8 Metro中的WrapGrid具有此属性。有人在WPF中有这个实现吗?
1 个解决方案
#1
4
There's an UniformWrapPanel article on codeproject.com, which I modified to ensure the items in a wrap panel have uniform width and fit to the width of the window. You should easily be able to modify this code to have a maximum number of columns. Try changing the code near
在codeproject.com上有一篇UniformWrapPanel文章,我对其进行了修改,以确保包装面板中的项目具有均匀的宽度并适合窗口的宽度。您应该可以轻松地修改此代码以获得最大列数。尝试更改附近的代码
var itemsPerRow = (int) (totalWidth/ItemWidth);
in order to specify the max columns.
为了指定最大列。
Here's the code:
这是代码:
public enum ItemSize
{
None,
Uniform,
UniformStretchToFit
}
public class UniformWrapPanel : WrapPanel
{
public static readonly DependencyProperty ItemSizeProperty =
DependencyProperty.Register(
"ItemSize",
typeof (ItemSize),
typeof (UniformWrapPanel),
new FrameworkPropertyMetadata(
default(ItemSize),
FrameworkPropertyMetadataOptions.AffectsMeasure,
ItemSizeChanged));
private static void ItemSizeChanged(
DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var uniformWrapPanel = sender as UniformWrapPanel;
if (uniformWrapPanel != null)
{
if (uniformWrapPanel.Orientation == Orientation.Horizontal)
{
uniformWrapPanel.ItemWidth = double.NaN;
}
else
{
uniformWrapPanel.ItemHeight = double.NaN;
}
}
}
public ItemSize ItemSize
{
get { return (ItemSize) GetValue(ItemSizeProperty); }
set { SetValue(ItemSizeProperty, value); }
}
protected override Size MeasureOverride(Size availableSize)
{
var mode = ItemSize;
if (Children.Count > 0 && mode != ItemSize.None)
{
bool stretchToFit = mode == ItemSize.UniformStretchToFit;
if (Orientation == Orientation.Horizontal)
{
double totalWidth = availableSize.Width;
ItemWidth = 0.0;
foreach (UIElement el in Children)
{
el.Measure(availableSize);
Size next = el.DesiredSize;
if (!(Double.IsInfinity(next.Width) || Double.IsNaN(next.Width)))
{
ItemWidth = Math.Max(next.Width, ItemWidth);
}
}
if (stretchToFit)
{
if (!double.IsNaN(ItemWidth) && !double.IsInfinity(ItemWidth) && ItemWidth > 0)
{
var itemsPerRow = (int) (totalWidth/ItemWidth);
if (itemsPerRow > 0)
{
ItemWidth = totalWidth/itemsPerRow;
}
}
}
}
else
{
double totalHeight = availableSize.Height;
ItemHeight = 0.0;
foreach (UIElement el in Children)
{
el.Measure(availableSize);
Size next = el.DesiredSize;
if (!(Double.IsInfinity(next.Height) || Double.IsNaN(next.Height)))
{
ItemHeight = Math.Max(next.Height, ItemHeight);
}
}
if (stretchToFit)
{
if (!double.IsNaN(ItemHeight) && !double.IsInfinity(ItemHeight) && ItemHeight > 0)
{
var itemsPerColumn = (int) (totalHeight/ItemHeight);
if (itemsPerColumn > 0)
{
ItemHeight = totalHeight/itemsPerColumn;
}
}
}
}
}
return base.MeasureOverride(availableSize);
}
}
#1
4
There's an UniformWrapPanel article on codeproject.com, which I modified to ensure the items in a wrap panel have uniform width and fit to the width of the window. You should easily be able to modify this code to have a maximum number of columns. Try changing the code near
在codeproject.com上有一篇UniformWrapPanel文章,我对其进行了修改,以确保包装面板中的项目具有均匀的宽度并适合窗口的宽度。您应该可以轻松地修改此代码以获得最大列数。尝试更改附近的代码
var itemsPerRow = (int) (totalWidth/ItemWidth);
in order to specify the max columns.
为了指定最大列。
Here's the code:
这是代码:
public enum ItemSize
{
None,
Uniform,
UniformStretchToFit
}
public class UniformWrapPanel : WrapPanel
{
public static readonly DependencyProperty ItemSizeProperty =
DependencyProperty.Register(
"ItemSize",
typeof (ItemSize),
typeof (UniformWrapPanel),
new FrameworkPropertyMetadata(
default(ItemSize),
FrameworkPropertyMetadataOptions.AffectsMeasure,
ItemSizeChanged));
private static void ItemSizeChanged(
DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var uniformWrapPanel = sender as UniformWrapPanel;
if (uniformWrapPanel != null)
{
if (uniformWrapPanel.Orientation == Orientation.Horizontal)
{
uniformWrapPanel.ItemWidth = double.NaN;
}
else
{
uniformWrapPanel.ItemHeight = double.NaN;
}
}
}
public ItemSize ItemSize
{
get { return (ItemSize) GetValue(ItemSizeProperty); }
set { SetValue(ItemSizeProperty, value); }
}
protected override Size MeasureOverride(Size availableSize)
{
var mode = ItemSize;
if (Children.Count > 0 && mode != ItemSize.None)
{
bool stretchToFit = mode == ItemSize.UniformStretchToFit;
if (Orientation == Orientation.Horizontal)
{
double totalWidth = availableSize.Width;
ItemWidth = 0.0;
foreach (UIElement el in Children)
{
el.Measure(availableSize);
Size next = el.DesiredSize;
if (!(Double.IsInfinity(next.Width) || Double.IsNaN(next.Width)))
{
ItemWidth = Math.Max(next.Width, ItemWidth);
}
}
if (stretchToFit)
{
if (!double.IsNaN(ItemWidth) && !double.IsInfinity(ItemWidth) && ItemWidth > 0)
{
var itemsPerRow = (int) (totalWidth/ItemWidth);
if (itemsPerRow > 0)
{
ItemWidth = totalWidth/itemsPerRow;
}
}
}
}
else
{
double totalHeight = availableSize.Height;
ItemHeight = 0.0;
foreach (UIElement el in Children)
{
el.Measure(availableSize);
Size next = el.DesiredSize;
if (!(Double.IsInfinity(next.Height) || Double.IsNaN(next.Height)))
{
ItemHeight = Math.Max(next.Height, ItemHeight);
}
}
if (stretchToFit)
{
if (!double.IsNaN(ItemHeight) && !double.IsInfinity(ItemHeight) && ItemHeight > 0)
{
var itemsPerColumn = (int) (totalHeight/ItemHeight);
if (itemsPerColumn > 0)
{
ItemHeight = totalHeight/itemsPerColumn;
}
}
}
}
}
return base.MeasureOverride(availableSize);
}
}