我想知道使用LINQ是否可以编写一个简短的算法来实现它。
这就是我所说的。
我们假设您有List
500件。现在,出于性能原因,您不希望将此列表绑定到ListView
。相反,您只想显示其中的一部分,而当用户滚动时,您会加载下一个或之前的项目。
考虑以下方法:public List<MyItemType> GetPartOfList(bool next, int quantity);
您将如何完成,以便它返回包含某个数量项目的List
。 bool
参数告知您是否需要下一个或上一个项目。
当然,要避免使用OutOfBounds Exception
,您必须返回一个列表,其中包含较少的项目,但这样可以。
是否已经有这样的算法,因为我不想重建车轮?谢谢!
目前,这就是我所做的:
private int _currentIndexBeg = 0; // required to know where the current portion of the list starts
private int _currentIndexEnd = 0; // required to know where the current portion of the list stops
public ObservableCollection<T> GetPartOfConversation( bool less, int quantity )
{
if( quantity < 0 )
throw new ArgumentException( "quantity", "quantity MUST NOT be NEGATIVE!" );
if (quantity > _originalList.Count)
{
_currentIndexBeg = 0;
_currentIndexEnd = _originalList.Count;
return _originalList; // list is small enough
}
if (_currentIndexBeg == 0 && _currentIndexEnd == 0) // first time call
{
_currentIndexBeg = 0;
_currentIndexEnd = quantity;
return new ObserableCollection<T>(_originalList.GetRange(0, quantity); // safe, no risk of exception, already handled before
}
else
{
// now onto the fun part
if (less) //meaning we want the PREVIOUS "quantity" items
{
if( _currentIndexBeg == 0 ) // which means top in the list, no more items
return null; //if null, it means there is no other items to be displayed into the ListView. Requires a null check, that's still OK.
if (_currentIndexBeg - quantity < 0) // alright, we want the n previous items. But if there are previous items but not as much as we would want we could either return what remains,
// or what remains plus what already exists to make sure we return a List of quantity elements
{
// TODO
return null; // TODO
}
// here means that there is at least (equal or more) quantity elements that remains and can be displayed
// TODO
}
else //meaning we want the NEXT "quantity" items
{
if( _currentIndexEnd == _originalList.Count ) // which means bottom of the list, no more items
return null; //if null, it means there is no other items to be displayed into the ListView. Requires a null check, that's still OK.
if (_currentIndexEnd + quantity > originalList.Count) // aright, we want the n next items. But if there are indeed next available items, but not as much as we would want
// we could return what remains (less than quantity) or what remains + what already exists
{
int remain = originalList.Count - _currentIndexEnd - 1; // minus 1 because zero based indexation
return new ObserableCollection<T>(_originalList.GetRange(_currentIndexEnd , remain);
// OR
return new ObserableCollection<T>(_originalList.GetRange(_currentIndexEnd - (quantity - remain) , quantity); // to match the requested quantity
}
// here means that there is at least (equal or more) quantity elements that remains and can be displayed
// TODO
}
}
}
随着我的进步,我会更新代码,但如果我做了一些完全错误的事情,我想帮忙。谢谢!
更多说明:
ListView
显示两个用户之间的对话; List
包含代表&#34;聊天的自定义项目
气泡&#34; ; ListView
自动滚动到最后一个条目(最后一条消息)
使用ScrollIntoView()
;
我无法使用此处所述的Virtualisation
:https://stackoverflow.com/a/30765631/3535408 答案 0 :(得分:1)
你有没有探究过Virtualization
?这是内置功能,通过仅渲染可见内容来实现您所描述的内容。您仍然会绑定整个集合,但框架将处理渲染逻辑。您只需将VirtualizingStackPanel.IsVirtualizing
属性设置为true即可。根据您的代码判断,您已将整个列表保留在内存中,因此通过LINQ
进行批处理只会增加开销。有关其他详细信息,请参阅以下链接。
https://msdn.microsoft.com/en-us/library/cc716879(v=vs.110).aspx
How to enable UI virtualization in Standard WPF ListView
<强>更新强>
无法拥有Virtualization
和CanContentScroll='False'
(Is it possible to implement smooth scroll in a WPF listview?)。以下是一些想到的解决方法:
获取最新的N项,但是 允许用户延迟加载旧项目;这是一种采用的技术 许多聊天应用程序。但是,当用户加载更多项目时, 您将体验到您试图避免的性能损失。 通过这种方法,您只能对用户进行对冲 偶尔会关心较旧的对话。
将ListView
中的项目限制为a
可管理的号码,并允许用户访问不同的页面
查看扩展的聊天记录。
如果你有房地产,你也可以增加高度
ListView
和/或减少要显示的项目的高度
一次更多的项目,这应该有效地减慢你的滚动速度。 (另)
答案 1 :(得分:0)
在linq中,最好的方法是使用Skip和Take方法。
Iterable
在您的代码中,您只需在用户滚动时知道“页面”编号。