【问题标题】:Do not show partial items in a WPF listbox不在 WPF 列表框中显示部分项目
【发布时间】:2010-03-30 15:48:54
【问题描述】:

我尝试过 Google,也尝试过 Bing,但无济于事。这里有没有人知道如何防止部分项目出现在 WPF 的列表框中?如果这没有意义,这里是一个示例:列表框高 200 像素 - 每个项目高 35 像素。这意味着我可以展示 5.7 个项目。一个项目的 7/10 是不可取的。我想将其限制为仅显示 5 个项目。然后用户可以滚动查看附加项目。

我应该 A) 尝试动态调整列表框或 ScrollViewer ViewPort 的大小以使其完美匹配吗?或者 B) 实现一个自定义面板,该面板不会排列所需高度大于剩余垂直空间的孩子?

任何想法将不胜感激。最后一点:如果有人知道这样做的第 3 方控件(列表框或网格),我也会对此感兴趣。

【问题讨论】:

  • 嗯,嗯,在 WinForms 中,ListBox 有一个设置:IntegralHeight AFAIK,WPF ListBox 没有。

标签: wpf listbox


【解决方案1】:

只需在设计器中调整它的大小,直到您没有得到部分行。对于这样的事情,实现自定义面板的工作量太大了。

您也可以尝试使用ListView 而不是ListBox。我可能记错了,但我认为 ListView 不显示部分,或者可能有不显示部分行的选项。

【讨论】:

  • 我会看看列表视图。我们无法预先设置列表框的大小。当/如果用户调整窗口大小时,它的高度会增加。
  • 感谢您,David 正确处理调整大小!不这样做是我的主要烦恼。
  • 其实,我真正的答案应该是:“不要打扰”。您所描述的是正常的列表框行为;我怀疑您是否会因此而失去任何客户。
  • 我们的列表框项目是交互式的(它们有数字向上/向下微调按钮)。当底部显示 90% 的项目时,用户尝试单击向上/向下按钮,WPF 会重新定位该项目。现在他们的鼠标在下一个项目上。如果他们不知道他们将编辑错误的项目。
  • @David:这完全有道理。我很抱歉参与了标准的 StackOverflow 行为,即假设我比提问的人更了解。根据您的描述,我可能使用包装或继承自 Panel 的自定义控件。
【解决方案2】:

我今天一直在考虑这个问题,因为我的项目一直在解决这个问题。我的想法与我的项目有关,但应该适用。我假设是 MVVM ViewModel,但没有它也可以工作。

将属性绑定到 ListBox 所在容器的高度,然后使用 ValueConverter 将 ListBox 的高度绑定到该高度,以使 ListBox 根据单个项目的高度分阶段扩展或收缩。这在调整大小时可能看起来有点滑稽,但如果有一个简短的动画效果会很好。

【讨论】:

  • 你能详细说明一下这个答案吗?
  • 这个周末我会尝试抛出一个简单的示例
【解决方案3】:

您可以通过在 dispather 中找到列表框内容的实际高度并调整列表框的高度来实现这一点,但是,它会使列表框的大小根据实现而增大或缩小。

【讨论】:

    【解决方案4】:

    我的投票是每个项目的自定义面板。如果无法完全显示该面板,则不会显示该面板。该列表可以根据需要调整大小,因为它的唯一工作是成为一个可调整大小的容器,为面板提供一个区域。面板可以根据需要增长和缩小。

    【讨论】:

      【解决方案5】:

      我的解决方案是使用一个多值转换器,它将层次结构中的ListBoxScrollViewerListBoxItem 以及列表框ActualHeight、滚动查看器@ 作为输入987654325@ 和列表框项ActualHeight 并返回可见性。树的最后一个(双精度)值仅用于确保转换器的 Convert 方法将在任何重大值更改时被调用。基本上,如果项目的底部大于滚动查看器的底部,则返回的VisibilityHidden,否则返回Visible

      这是转换器的代码:

      using System;
      using System.Globalization;
      using System.Linq;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Data;
      
      public class ListBoxItemToVisibilityConverter : IMultiValueConverter
      {
          public object Convert(
              object[] values,
              Type targetType,
              object parameter,
              CultureInfo culture)
          {
              if ((values?.Length ?? 0) != 6)
                  return Visibility.Collapsed;
      
              var listBox = values.OfType<ListBox>().FirstOrDefault();
              var scrollViewer = values.OfType<ScrollViewer>().FirstOrDefault();
              var listBoxItem = values.OfType<ListBoxItem>().FirstOrDefault();
      
              var heights = values.OfType<double>().ToArray();
      
              if (new object[] { listBox, scrollViewer, listBoxItem }.Any(item => item == null) || heights.Length != 3)
                  return Visibility.Collapsed;
      
              var scrollViewerBottom = scrollViewer.PointToScreen(new Point(0, scrollViewer.ActualHeight)).Y;
              var listBoxItemBottom = listBoxItem.PointToScreen(new Point(0, listBoxItem.ActualHeight)).Y;
      
              return listBoxItemBottom > scrollViewerBottom ? Visibility.Hidden : Visibility.Visible;
          }
      
          public object[] ConvertBack(
              object value,
              Type[] targetTypes,
              object parameter,
              CultureInfo culture) =>
              throw new NotSupportedException();
      }
      

      它的声明:

      <local:ListBoxItemToVisibilityConverter x:Key="ListBoxItemToVisibility"/>
      

      它在项目模板中的用法:

      <DataTemplate>
          <Button Content="{Binding Text}">
              <Button.Visibility>
                  <MultiBinding Converter="{StaticResource ListBoxItemToVisibility}">
                      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBoxItem}"/>
                      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ScrollViewer}"/>
                      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}"/>
                      <Binding Path="ActualHeight" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBoxItem}"/>
                      <Binding Path="VerticalOffset" RelativeSource="{RelativeSource FindAncestor, AncestorType=ScrollViewer}"/>
                      <Binding Path="ActualHeight" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}"/>
                  </MultiBinding>
              </Button.Visibility>
          </Button>
      </DataTemplate>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-19
        • 1970-01-01
        • 1970-01-01
        • 2016-03-22
        • 2016-08-31
        • 2016-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多