不要在WPF列表框中显示部分项
我试过谷歌,也试过必应,但都没用。这里有人知道如何防止WPF中的列表框中出现部分项目吗?在这种情况下,这里是一个没有意义的例子:列表框是200像素高-每个项目是35像素高。这意味着我可以显示5.7项。一个项目的7/10是不可取的。我想限制它只显示5个项目。然后,用户可以滚动查看其他项目 我是否应该A)尝试动态调整listbox或ScrollViewer视口的大小,使其完全适合?或B)实施自定义面板,该面板不会安排所需高度大于剩余垂直空间的儿童不要在WPF列表框中显示部分项,wpf,listbox,Wpf,Listbox,我试过谷歌,也试过必应,但都没用。这里有人知道如何防止WPF中的列表框中出现部分项目吗?在这种情况下,这里是一个没有意义的例子:列表框是200像素高-每个项目是35像素高。这意味着我可以显示5.7项。一个项目的7/10是不可取的。我想限制它只显示5个项目。然后,用户可以滚动查看其他项目 我是否应该A)尝试动态调整listbox或ScrollViewer视口的大小,使其完全适合?或B)实施自定义面板,该面板不会安排所需高度大于剩余垂直空间的儿童 任何想法都将不胜感激。最后一点注意:如果有人知道第三
任何想法都将不胜感激。最后一点注意:如果有人知道第三方控件(listbox或grid)可以执行此操作,我也会对此感兴趣。只需在设计器中调整它的大小,直到没有部分行为止。实现一个自定义面板对于这样的东西来说是太多的工作了
您也可以尝试使用
列表视图
而不是列表框
。我可能记错了,但我认为列表视图不显示部分行,或者可能有不显示部分行的选项。我今天一直在考虑这个问题,因为我的项目一直在解决这个问题。我的想法与我的项目相关,但应该适用。我假设使用MVVM ViewModel,但如果没有它,它也可以工作
将属性绑定到ListBox所在容器的高度,然后使用ValueConverter将ListBox的高度绑定到该容器的高度,以使ListBox根据单个项目的高度分阶段展开或收缩。调整大小时,这可能看起来有点滑稽,但使用一个简短的动画可以看起来很好。您可以通过在dispather中查找列表框内容的实际高度并调整列表框的高度来实现这一点,但是,它将使列表框大小根据实现的不同而增大或缩小。我的投票是每个项目的自定义面板。如果无法完全显示自身,则不会显示此面板。列表可以根据需要调整大小,因为它唯一的任务是成为一个可调整大小的容器,为面板提供一个区域。面板可以根据需要增减。我的解决方案是使用一个多值转换器,将层次结构中的列表框
、滚动查看器
和列表框项
以及列表框
实际高度、滚动查看器垂直偏移量作为输入,和列表框项ActualHeight
,并返回可见性。树的最后一个(双精度)值仅用于确保转换器的Convert
方法在任何重要值更改时被调用。基本上,如果项目的底部大于滚动查看器的底部,则返回的可见性
为隐藏
,而可见
为其他
以下是转换器的代码:
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();
}
使用系统;
利用制度全球化;
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
公共类ListBoxItemToVisibilityConverter:IMultiValueConverter
{
公共对象转换(
对象[]值,
类型targetType,
对象参数,
文化信息(文化)
{
如果((值?.Length±0)!=6)
返回可见性。折叠;
var listBox=values.OfType().FirstOrDefault();
var scrollViewer=values.OfType().FirstOrDefault();
var listBoxItem=values.OfType().FirstOrDefault();
var heights=value.OfType().ToArray();
if(新对象[]{listBox,scrollViewer,listBoxItem}.Any(item=>item==null)| heights.Length!=3)
返回可见性。折叠;
var scrollViewerBottom=scrollViewer.PointToScreen(新点(0,scrollViewer.ActualHeight)).Y;
var listBoxItemBottom=listBoxItem.PointToScreen(新点(0,listBoxItem.ActualHeight)).Y;
返回listBoxItemBottom>scrollViewerBottom?可见性。隐藏:可见性。可见;
}
公共对象[]返回(
对象值,
类型[]目标类型,
对象参数,
文化信息文化)=>
抛出新的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>
我将查看列表视图。我们无法预先调整列表框的大小。当/如果用户调整窗口大小,它的高度会增加。大卫,正确处理调整大小对你很好!不这样做是我最讨厌的事。事实上,我真正的答案应该是:“不要麻烦”。您所描述的是正常的列表框行为;我怀疑你是否会因此失去任何客户。我们的列表框项目是交互式的(它们有数字上/下微调按钮)。当底部显示90%的项目时,用户尝试单击向上/向下按钮,WPF会重新定位该项目。现在,他们的鼠标位于下一项上。如果他们不知道,他们将编辑错误的项目。@David:这完全有道理。很抱歉,我做出了标准的StackOverflow行为,认为我比提问的人更清楚。根据您所描述的,我可能会使用一个自定义控件,它可以包装或继承Panel.hmmm,好吧,在WinForms中,ListBox有一个设置:IntegralHeight AFAIK,WPF ListBox没有。您能给这个答案提供更多细节吗?这个周末我将尝试提供一个简单的示例