2016-09-21 85 views
2

有人可以帮助我,我怎么能更新ObservableCollection,绑定到ListView的ItemSource,而不眨眼?当我这样做时:更新ObservableCollection不闪烁

Contacs = _contacs; 

整个ListView闪烁。我想在ListView中进行搜索,但总是在用新的结果替换旧的结果后,ListView闪烁。

+0

你是什么意思的更新?你是否替换整个OC,或添加/删除记录。 – AnjumSKhan

+0

我替换整个集合。 – JuP

+0

@rbm你说的“双缓冲”与问题问题完全没有关系。用户要求更好的方式来通知UI在后台发生了什么。双缓冲区是一种位图优化技术,仅对Winforms有效(不在UWP/WPF中) –

回答

2

这里的问题是,你正在重新分配整个集合。这没有利用可观察性,并强制ListView重新加载所有项目。尝试删除/添加项目,所以ListView只需要更新实际更改的项目。

在搜索隐藏的情况下,不匹配的结果也可能是一个可行的解决方案。为此,请在联系人类型(例如,称为“IsVisible”)上创建一个属性,并将其绑定到ListViewItems可见性属性。 (您可能需要在BooleanToVisibility转换这里的版本)

更新

如使用CollectionViewSource评论中指出的是实现一个搜索过滤器的正确WPF方式。有关如何使用它的详细信息,请参阅this答案。

+0

它是有道理的,当我用新数据替换集合时,它闪烁。所以我应该只使用现有的源代码并添加/删除项目。您的搜索解决方案很好。 – JuP

+0

这是一个很好的黑客攻击,但是当你拥有使用CollectionViewSource和ICollectionView的内置功能时,你不需要它。 –

+0

你当然是对的。我链接你的答案 – vkluge

1

如果你想在你的集合中启用过滤,那么就没有必要直接在你的集合上执行操作。为此目的,使用ICollectionViewCollectionViewSource

因为你有一个ObservableCollection所以你可以做这样的事情。

ICollectionView contactsView; 

public ICollectionView ContactsView 
{ 
    get { return contactsView; } 
    set 
    { 
     if(contactsView != value) 
     { 
      contactsView = value; 
     } 
    } 
} 

而在ObservableCollection

public ObservableCollection<ContactType> Contacs 
{ 
    get { return _contacs; } 
    set 
    { 
     if(_contacs != value) 
     { 
     _contacs = value; 
     ContactsView = CollectionViewSource.GetDefaultView(value); 
     ContactsView.Filter = ContactsFilter; 
     } 
    } 
} 

其中ContactsFilter的二传手是如下定义的函数。

bool ContactsFilter(object item) 
{ 
    var contact = item as ContactType; 

    if(condition) 
    return true; //show this item in ListView. 

    return false; //Do not show this item in ListView 
} 

,只要你想仅仅通过

ContactsView.Refresh(); 

,我认为将是TextChanged事件中,正在输入搜索查询的文本框的筛选,你可以做的项目。

更详细的文章在CollectionViewSource

+0

谢谢。我会尝试。 :) – JuP

+0

当然。让我知道事情的后续。我推荐这是因为它分离了你的过滤逻辑。 –

+0

我有一个问题。属性过滤器不在UWP中:/ – JuP