【问题标题】:Limit number of displayed items in WPF ListView限制 WPF ListView 中显示项目的数量
【发布时间】:2016-08-18 10:06:40
【问题描述】:

所以我有一个由ObservableCollection<> 支持的ListView 控件,它会定期将项目添加到其中。但是我只想显示最多前 10 个项目;也就是说,如果最多有 10 个项目,它会全部显示它们,同时相应地调整大小,如果超过 10 个,它会在第 10 个项目停止显示它们。

我想知道是否有合理的方法来做到这一点,因为我目前的直觉是有第二个集合,它反映 ItemsSource 的前 10 个项目,并相应地更新。

【问题讨论】:

  • 不是第二个集合,而是过滤您的集合以仅显示前 10 个项目怎么样?
  • 我不知道该怎么做。我需要维护底层集合,所以我怕我不知道将ListView的ItemsSource绑定到什么,或者如何过滤它拥有的ItemsSource。
  • @Pikoh的思路是对的,article也有很好的过滤例子。
  • 那么在使用过滤的时候,应该什么时候启动过滤呢?我目前正在尝试在构造函数中实现它,但得到了NullRefernceErrorException,因为我认为 ItemsSource 尚未设置,因为它被绑定在 Xaml 中并且没有在加载时立即填充。
  • 那么您的收藏何时被填充?

标签: c# wpf listview observablecollection


【解决方案1】:

你可以做这样的事情(我还没有测试过,但你可能会明白):

_defaultView = CollectionViewSource.GetDefaultView(YourCollection);
_defaultView.SortDescriptions.Add(new System.ComponentModel.SortDescription(".", System.ComponentModel.ListSortDirection.Ascending));
_defaultView.Filter = o =>
{
    int index = YourCollection.OrderBy(s => s).ToList().IndexOf(o as string);
    return index >= 0 && index < 10;
};
_defaultView.Refresh();

【讨论】:

  • 我认为应该去你收集更改的地方(你说定期添加项目,所以我认为你应该在那之后这样做)
  • 可能只有Refresh() 语句应该在集合更改处理程序中,而所有视图的初始化(以及Refresh)都应该放在InitializeComponent() 指令之后的构造函数中。
  • 好的,所以我已经完成了大部分工作,但是出现了一个新问题。在添加每个对象时对每个对象进行过滤,但是我需要它做的是每次完全刷新整个集合的过滤
  • 在为ListView.ItemSourceProperty 设置处理程序之后,我使用上面的方法对其进行了排序,然后将处理程序添加到我的ObservableCollection&lt;&gt;.CollectionChanged 事件以使其保持更新。
【解决方案2】:

我更喜欢为此使用转换器,而不是添加新的模型值或其他额外的集合,因为这通常会干扰更改跟踪。

以下过滤器将列表设置为固定大小 10:

<ItemsControl ItemsSource="{Binding Configuration.RecentDocuments,Converter={StaticResource ItemSourceCountFilterConverter},ConverterParameter=10}" 

这个转换器基本上采用原始的 IEnumerable 并将其过滤到所需的项目数并返回它:

public  class ItemSourceCountFilterConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var val = value as IEnumerable;
        if (val == null)
            return value;

        int take = 10;
        if (parameter != null)
            int.TryParse(parameter as string, out take);


        if (take < 1)
            return value;
        var list = new List<object>();

        int count = 0;
        foreach (var li in val)
        {
            count++;
            if(count > take)
                break;
            list.Add(li);
        }
        return list;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

    猜你喜欢
    • 2021-09-16
    • 1970-01-01
    • 2010-11-12
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    相关资源
    最近更新 更多