WPF ListBox WrapPanel剪辑长组

WPF ListBox WrapPanel剪辑长组

WPF ListBox WrapPanel clips long groups

我已经创建了一个ListBox来显示组中的项目,当这些组不再适合ListBox的面板高度时,将这些组从右向左包裹。因此,组在列表框中的显示类似于此,其中每个组的高度是任意的(例如,组1的高度是组2的两倍):

1
2
3
[ 1 ][ 3 ][ 5 ]
[   ][ 4 ][ 6 ]
[ 2 ][   ]

以下XAML可以正常工作,因为它执行了package,并且当项目从ListBox的右侧运行时,允许水平滚动条出现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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中Height绑定的副作用-滚动条认为不必启用它。

是否有任何启用滚动条的方法,或者解决了我没有看到的此问题的另一种方法?


这里是经过略微修改的代码-先前发布该代码的所有人员均归功于Abe Heidebrecht-该代码允许水平和垂直滚动。唯一的变化是MeasureOverride的返回值必须为base.MeasureOverride(new Size(ret.width,h))。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 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));
  }
}

通过将WrapPanel上的Height属性设置为ScrollContentPresenter的高度,它将永远不会垂直滚动。但是,如果删除该Binding,它将永远不会换行,因为在布局传递中,它在布局中的高度是无限的。

我建议您创建自己的面板类以获取所需的行为。有一个单独的依赖项属性,可以将所需的高度绑定到该属性,因此可以使用该属性来计算度量中的目标高度并安排步骤。如果任何一个孩子的身高超过所需的身高,请使用该孩子的身高作为目标身高,以计算包裹率。

以下是执行此操作的示例面板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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));
    }
}

大卫,谢谢您的回答。

当绑定为removed时,不会发生换行。 WrapPanel将每个组放入单个垂直列中。

该绑定用于强制WrapPanel实际package。如果未设置任何绑定,则WrapPanel假定高度为无限且从不环绕。

绑定到MinHeight会导致一个空的列表框。我可以看到VerticalAlignment属性似乎是一个解决方案,但是对齐本身可以防止发生任何换行。当绑定和对齐方式一起使用时,对齐方式不会对问题产生影响。


我认为您与绑定有关是正确的。删除绑定后会发生什么?通过绑定,您是否要填充至少列表框的整个高度?如果是这样,请考虑绑定到MinHeight,或者尝试使用VerticalAlignment属性。


推荐阅读

    linux显示错误命令?

    linux显示错误命令?,信息,系统,电脑,状态,时间,环境,命令,搜狐,密码,异常,虚

    linux逐行显示命令?

    linux逐行显示命令?,标准,信息,系统,工作,地址,命令,实时,名称,文件,目录,Lin

    linux显示时间命令?

    linux显示时间命令?,时间,系统,管理,标准,信息,单位,工具,数据,中国,命令,lin

    linux启动显示命令行?

    linux启动显示命令行?,系统,密码,终端,状态,首页,情况,基础,电脑,信息,工具,l

    linux启动显示命令行?

    linux启动显示命令行?,系统,密码,终端,状态,首页,情况,基础,电脑,信息,工具,l

    linux显示之前的命令?

    linux显示之前的命令?,系统,信息,命令,地址,服务,环境,数据,标准,数字,不了,l

    linux打开显示器命令?

    linux打开显示器命令?,信息,工具,系统,环境,发行,实时,数据,设备,命令,文件,L

    linux命令实时显示?

    linux命令实时显示?,系统,实时,时间,信息,情况,命令,对比,电脑,名称,一致,lin

    linux外部命令显示?

    linux外部命令显示?,系统,工具,命令,一致,盘中,软件,技术,外部,内部,文件夹,L

    linux命令显示ip?

    linux命令显示ip?,地址,系统,网络,信息,技术,电脑,手机,设备,服务,管理,配置L

    linux编译时显示命令?

    linux编译时显示命令?,系统,基础,工具,代码,百度,下来,网上,命令,内核,文件,L

    linux显示运行命令?

    linux显示运行命令?,系统,服务,状态,信息,工具,数据,电脑,标准,管理,时间,如

    显示linux网卡命令行?

    显示linux网卡命令行?,系统,信息,工具,网络,服务,电脑,网卡,技术指标,地址,

    linux命令显示内容?

    linux命令显示内容?,标准,系统,数据,命令,百度,实时,时间,信息,文件,内容,lin

    linux常用显示命令?

    linux常用显示命令?,工作,地址,系统,信息,管理,命令,目录,标准,功能,常用命

    linux用命令显示账号?

    linux用命令显示账号?,密码,系统,信息,地址,电脑,名字,用户,命令,用户名,用

    linux命令行同步显示?

    linux命令行同步显示?,地址,工具,系统,数据,工作,时间,命令,综合,网址,信息,L

    linux命令显示窗口?

    linux命令显示窗口?,系统,工具,首页,终端,密码,命令,窗口,界面,桌面,选项,lin

    linux分页显示命令?

    linux分页显示命令?,工具,通信,命令,数据,信息,管道,标准,位置,一致,系统,lin

    linux中ps命令显示?

    linux中ps命令显示?,系统,信息,状态,进程,命令,多地,软件,工作,基础,报告,lin