我创建了一个ListBox来显示组中的项目,当它们不再适合ListBox面板的高度时,这些组从右到左包装。因此,这些组在列表框中看起来与此类似,其中每个组的高度是任意的(例如,组1的高度是组2的两倍):
[ 1 ][ 3 ][ 5 ]
[ ][ 4 ][ 6 ]
[ 2 ][ ]
以下XAML正常工作,因为它执行换行,并允许在项目从ListBox右侧运行时出现水平滚动条。
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.GroupStyle>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"
Height="{Binding Path=ActualHeight,
RelativeSource={RelativeSource
FindAncestor,
AncestorLevel=1,
AncestorType={x:Type ScrollContentPresenter}}}"/>
</ItemsPanelTemplate>
</ListBox.GroupStyle>
</ListBox>
当一组项目的长度超过WrapPanel的高度时,会出现问题。不是允许垂直滚动条显示以查看截止项组,而是简单地剪切该组中的项目。我假设这是WrapPanel中高度绑定的副作用 - 滚动条认为它不必启用。
有没有办法启用滚动条,或者我没有看到这个问题的其他方法?
答案 0 :(得分:2)
通过将WrapPanel上的Height属性设置为ScrollContentPresenter的高度,它将永远不会垂直滚动。但是,如果删除该Binding,它将永远不会换行,因为在布局过程中,它具有无限的布局高度。
我建议您创建自己的面板类以获得所需的行为。有一个单独的依赖项属性可以绑定所需的高度,因此您可以使用它来计算度量中的目标高度并排列步骤。如果任何一个孩子的身高高于所需的身高,请使用该孩子的身高作为目标身高来计算包裹。
以下是执行此操作的示例面板:
public class SmartWrapPanel : WrapPanel
{
/// <summary>
/// Identifies the DesiredHeight dependency property
/// </summary>
public static readonly DependencyProperty DesiredHeightProperty = DependencyProperty.Register(
"DesiredHeight",
typeof(double),
typeof(SmartWrapPanel),
new FrameworkPropertyMetadata(Double.NaN,
FrameworkPropertyMetadataOptions.AffectsArrange |
FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
/// Gets or sets the height to attempt to be. If any child is taller than this, will use the child's height.
/// </summary>
public double DesiredHeight
{
get { return (double)GetValue(DesiredHeightProperty); }
set { SetValue(DesiredHeightProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
Size ret = base.MeasureOverride(constraint);
double h = ret.Height;
if (!Double.IsNaN(DesiredHeight))
{
h = DesiredHeight;
foreach (UIElement child in Children)
{
if (child.DesiredSize.Height > h)
h = child.DesiredSize.Height;
}
}
return new Size(ret.Width, h);
}
protected override System.Windows.Size ArrangeOverride(Size finalSize)
{
double h = finalSize.Height;
if (!Double.IsNaN(DesiredHeight))
{
h = DesiredHeight;
foreach (UIElement child in Children)
{
if (child.DesiredSize.Height > h)
h = child.DesiredSize.Height;
}
}
return base.ArrangeOverride(new Size(finalSize.Width, h));
}
}
答案 1 :(得分:2)
这是稍微修改过的代码 - 所有信用都给予了之前发布的Abe Heidebrecht,允许水平和垂直滚动。唯一的变化是MeasureOverride的返回值需要为base.MeasureOverride(new size(ret.width,h))。
// Original code : Abe Heidebrecht
public class SmartWrapPanel : WrapPanel
{
/// <summary>
/// Identifies the DesiredHeight dependency property
/// </summary>
public static readonly DependencyProperty DesiredHeightProperty = DependencyProperty.Register(
"DesiredHeight",
typeof(double),
typeof(SmartWrapPanel),
new FrameworkPropertyMetadata(Double.NaN,
FrameworkPropertyMetadataOptions.AffectsArrange |
FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
/// Gets or sets the height to attempt to be. If any child is taller than this, will use the child's height.
/// </summary>
public double DesiredHeight
{
get { return (double)GetValue(DesiredHeightProperty); }
set { SetValue(DesiredHeightProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
Size ret = base.MeasureOverride(constraint);
double h = ret.Height;
if (!Double.IsNaN(DesiredHeight))
{
h = DesiredHeight;
foreach (UIElement child in Children)
{
if (child.DesiredSize.Height > h)
h = child.DesiredSize.Height;
}
}
return base.MeasureOverride(new Size(ret.Width, h));
}
protected override System.Windows.Size ArrangeOverride(Size finalSize)
{
double h = finalSize.Height;
if (!Double.IsNaN(DesiredHeight))
{
h = DesiredHeight;
foreach (UIElement child in Children)
{
if (child.DesiredSize.Height > h)
h = child.DesiredSize.Height;
}
}
return base.ArrangeOverride(new Size(finalSize.Width, h));
}
}
答案 2 :(得分:0)
我认为你是正确的,它与绑定有关。删除绑定后会发生什么?你试图填充至少列表框的整个高度?如果是这样,请考虑绑定到MinHeight,或尝试使用VerticalAlignment
属性。
答案 3 :(得分:0)
感谢大卫回答。
当绑定为removed
时,不会发生包装。 WrapPanel 会将每个组放入一个垂直列中。
绑定意味着强制WrapPanel实际换行。如果未设置绑定,则WrapPanel假定高度为无限且永不包裹。
绑定到MinHeight
会导致空列表框。我可以看到VerticalAlignment
属性似乎是一个解决方案,但是对齐本身可以防止任何包装发生。当绑定和对齐一起使用时,对齐对问题没有影响。