我有ObservableCollection<T>集合,我想用新的元素集合替换所有元素,我可以这样做:
collection.Clear();
Run Code Online (Sandbox Code Playgroud)
要么:
collection.ClearItems();
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,这两种方法有什么区别?)
我也foreach可以collection.Add一个接一个地使用,但这会多次发射
添加元素集合时也一样.
编辑:
我在这里找到了一个很好的库:增强的ObservableCollection能够延迟或禁用通知,但它似乎不支持silverlight.
正在考虑System.Collections.ObjectModel ObservableCollection<T>上课.这个很奇怪,因为
我需要的是将一批对象添加到集合中,并且侦听器还将批处理作为通知的一部分.我错过了ObservableCollection的东西吗?还有其他课程符合我的规范吗?
更新:尽量不要自己动手.我必须建立添加/删除/更改等等.很多东西.
相关问:https:
//stackoverflow.com/questions/670577/observablecollection-doesnt-support-addrange-method-so-i-get-notified-for-each
我有一个ObservableCollection项目绑定到我的视图中的列表控件.
我有一种情况需要在集合的开头添加一大块值.
Collection<T>.Insertdocumentation将每个插入指定为O(n)操作,每个插入也生成一个CollectionChanged通知.
因此,我理想地希望在一次移动中插入整个范围的项目,这意味着只有一个基础列表的随机播放,并且希望有一个CollectionChanged通知(可能是"重置").
Collection<T>不公开任何执行此操作的方法.List<T>有InsertRange(),但是IList<T>,这Collection<T>暴露了通过其Items属性不会.
有没有办法做到这一点?
我有一个ObservableCollection,我想将IList的内容设置为这个.现在我可以创建一个新的集合实例..:
public ObservableCollection<Bar> obs = new ObservableCollection<Bar>();
public void Foo(IList<Bar> list)
{
obs = new ObservableCollection<Bar>(list);
}
Run Code Online (Sandbox Code Playgroud)
但是,我怎样才能真正获取IList的内容并将其添加到我现有的ObservableCollection中?我是否必须遍历所有元素,还是有更好的方法?
public void Foo(IList<Bar> list)
{
foreach (var elm in list)
obs.Add(elm);
}
Run Code Online (Sandbox Code Playgroud) 我有一个使用MVVM数据绑定的WPF应用程序.我正在为一个ObservableCollection<...>和其中很多人添加项目.
现在我想知道每次我在集合中添加一个,是否会立即触发事件并导致不必要的开销?如果是这样,我可以以某种方式暂时禁用事件通知并在我的代码结束时手动触发一次,这样如果我添加10k项,它只会被触发一次,而不是10k次?
更新:我尝试过这门课程:
using System;
using System.Linq;
using System.Collections.Specialized;
using System.Collections.Generic;
namespace MyProject
{
/// <summary>
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>
{
/// <summary>
/// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
/// </summary>
public void AddRange(IEnumerable<T> collection)
{
foreach (var i in collection) Items.Add(i); …Run Code Online (Sandbox Code Playgroud) 我有ListView(默认情况下虚拟化),它ItemsSource绑定到ObservableCollection<Item>属性.
当填充数据(设置属性并且通知上升)时,我在分析器中看到2个布局峰值,第二个在调用后发生listView.ScrollIntoView().
我的理解是:
ListView通过绑定加载数据ListViewItem,并从索引0开始为屏幕上的项创建.listView.ScrollIntoView().ListView第二次(创造ListViewItems).如何防止去虚拟化发生两次(我之前不希望ScrollIntoView发生这种情况)?
我试着用一个repro ListBox.
XAML:
<Grid>
<ListBox x:Name="listBox" ItemsSource="{Binding Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Content="Fill" VerticalAlignment="Top" HorizontalAlignment="Center" Click="Button_Click" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
CS:
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public class ViewModel : …Run Code Online (Sandbox Code Playgroud) 是什么引起的潜在问题,ObservableCollection像支持操作AddRange或RemoveRange?由于ObservableCollection经常与WPF一起使用,因此必须有微软没有提供它们的原因.
您可以实现自己的集合,支持批量操作和实现INotifyCollectionChanged.如果我将这样的控件绑定到ItemsControl会发生什么?
有谁知道不支持批量更改的ItemsControls?
目前我有两个模仿以下功能的WPF列表框
Word 2007自定义屏幕http://tlt.its.psu.edu/suggestions/international/graphics/vista/WordCustomize.gif
我正在使用2个ObservableCollections来允许用户选择他们需要的任何项目(灵活性是这里的关键).主要问题是我有两千个项目在两个列表框中分组.总而言之,设计工作非常好(有几十个项目),但我的绊脚石是用户在屏幕冻结时从左到右复制所有可用的项目(在不同的线程上运行的时间?).
看看ObservableCollection它没有AddRange方法,互联网上有各种各样的实现.我也知道CollectionChanged事件是不必要的被触发,因为每个项目都被严重复制在排水性能上.
很可能我不得不允许用户在将来从超过10,000个项目的组中进行选择,这听起来是个坏主意,但由于列表框(CollectionViewSource)上的分组工作得很好,但是不可协商,但是关闭两个列表框的虚拟化的副作用
在数据绑定到ObservableCollection时,如何在加载包含数千个项目的列表框时,如何提高性能?是否有推荐的AddRange类型实现?我在这里唯一的选择是在后台线程上运行它,这看起来很昂贵,因为我没有从数据库加载数据?
虽然BindingList<T>并ObservableCollection<T>提供了检测列表更改的机制,但它们不支持在更改发生之前检测/拦截更改的机制.
我正在写几个接口来支持这个,但我想画出你的意见.
选项1:列表为每种类型的操作引发事件
在这里,消费者可能会编写如下代码:
public class Order : Entity
{
public Order()
{
this.OrderItems = new List<OrderItem>();
this.OrderItems.InsertingItem += new ListChangingEventHandler<OrderItem>(OrderItems_InsertingItem);
this.OrderItems.SettingItem += new ListChangingEventHandler<OrderItem>(OrderItems_SettingItem);
this.OrderItems.RemovingItem += new ListChangingEventHandler<OrderItem>(OrderItems_RemovingItem);
}
virtual public List<OrderItem> OrderItems { get; internal set; }
void OrderItems_InsertingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this;
}
void OrderItems_SettingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this; …Run Code Online (Sandbox Code Playgroud) 我有一点问题,我有一个数组,我想在Combobox中添加它,所以我想使用AddRange方法,但它在WPF中不可用,有没有办法可以在组合框中完成?
谢谢.
有没有办法暂停NotifyCollectionChanged一个ObservableCollection?我想到如下内容:
public class PausibleObservableCollection<Message> : ObservableCollection<Message>
{
public bool IsBindingPaused { get; set; }
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (!IsBindingPaused)
base.OnCollectionChanged(e);
}
}
Run Code Online (Sandbox Code Playgroud)
这确实暂停了通知,但显然当时我们遗漏了(但仍然添加了)项目NotifyCollectionChangedEventArgs,因此当我再次启用通知时,它们不会传递给绑定的DataGrid.
我是否必须想出一个集合的自定义实现来控制这个方面?
我正在为ObservableCollection编写一个扩展方法,并且已经读过.Add函数每次调用会引发3个属性更改事件,
所以这样的事情是个坏主意:
public static void AddRange<T>(this ObservableCollection<T> oc, IEnumerable<T> collection)
{
if (collection == null) { throw new ArgumentNullException("collection"); }
foreach (var i in collection) { oc.Add(i); }
}
Run Code Online (Sandbox Code Playgroud)
还有其他解决方案吗?
c# extension-methods observablecollection mvvm inotifypropertychanged
c# ×10
wpf ×6
mvvm ×3
collections ×2
data-binding ×2
performance ×2
.net-3.5 ×1
addrange ×1
bindinglist ×1
combobox ×1
insert ×1
list ×1
listbox ×1
listview ×1
silverlight ×1