标签: observablecollection

ObservableCollection(Of T)vs BindingList(Of T)?

我在过去的两年里开发了一些基于Winforms Application的数据,一切正常.此应用程序构建在层(DataAccess,业务逻辑和UI)上.对于Businness Logic,我的所有对象都继承自一个名为BaseEntity的基类,其定义如下(有一些自定义对象和接口,与框架元素结合):

Public MustInherit Class BaseEntity
    Inherits SerializableObject
    Implements IEntity
    Implements IComparer,  _
               IEditableObject,  _
               INotifyPropertyChanging, INotifyPropertyChanged,  _
               IApplicationSecurity
  End Class
Run Code Online (Sandbox Code Playgroud)

在同一个核心库中,我有一个通用的基本集合BaseEntityCollection.这些集合允许我为每个对象定义他的相关强类型集合,这在基于数据的应用程序中是非常有趣的.这是它的基本定义:

 Public MustInherit Class BaseEntityCollection(Of T As BaseEntity)
    Inherits BindingList(Of T)
    Implements IEntityCollection
    Implements INotifyPropertyChanged, INotifyPropertyChanging, ICopyable(Of T)
    Implements IDisposable
    Implements ISerializable
  End Class
Run Code Online (Sandbox Code Playgroud)

如您所见,我使用Winforms中正确数据绑定所需的所有内容:

  • 对象的INotifyPropertyChanged,INotifyPropertyChanging,IEditableObject.
  • 基于BindingList(Of T)的集合,用于我的集合.

我也对新技术感兴趣,所以我最近看了一些关于WPF的网络直播.在这些网络广播中,它们用作收集和数据绑定支持ObservableCollection(Of T)的基类.

我正在考虑将我的一些应用程序从Winforms迁移到WPF以用于UI层.

我的问题是,对于我的业务逻辑,最好是基于BindingList(Of T)保留我的集合,还是应该更改我的基本集合类以使其继承自ObservableCollection(Of T).我想为我的所有项目保留一个独特的基础集合,可以在Winforms应用程序,WPF应用程序或ASP.NET中使用.我也在我的项目中使用Linq to Objects,所以我没有限制只保留基于框架2.0的项目.

谢谢,

CLABER

data-binding bindinglist observablecollection winforms

23
推荐指数
2
解决办法
2万
查看次数

删除集合中的项目时,ObservableCollection依赖项属性不会更新

我在控件上有一个ObservableCollection类型的附加属性.如果我在集合中添加或删除项目,则ui不会更新.但是,如果我用新的替换集合,则ui会更新ViewModel.

有人能给我一个我在Dependency对象中需要做什么的例子,以便它可以处理集合中的变化吗?

下面列出了依赖项对象的一部分:

public class RadCalendarBehavior : DependencyObject
{
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  var calendar = d as RadCalendar;
  if (e.NewValue != null)
  {
    calendar.DayTemplateSelector = new SpecialDaySelector((ObservableCollection<DateTime>)e.NewValue, GetSpecialDayTemplate(d));
  }
}

public static ObservableCollection<DateTime> GetSpecialDays(DependencyObject obj)
{
  return (ObservableCollection<DateTime>)obj.GetValue(SpecialDaysProperty);
}

public static void SetSpecialDays(DependencyObject obj, ObservableCollection<DateTime> value)
{
  obj.SetValue(SpecialDaysProperty, value);
}

public static readonly DependencyProperty SpecialDaysProperty =
    DependencyProperty.RegisterAttached("SpecialDays", typeof(ObservableCollection<DateTime>), typeof(RadCalendarBehavior), new UIPropertyMetadata(null, OnSpecialDaysChanged));
}
}
Run Code Online (Sandbox Code Playgroud)

我知道我需要注册该集合已经更改,但我不确定如何在依赖项属性中执行此操作

wpf dependency-properties observablecollection

23
推荐指数
3
解决办法
1万
查看次数

将IList中的元素添加到ObservableCollection

我有一个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)

c# list observablecollection

22
推荐指数
2
解决办法
3万
查看次数

.NET 4中是否有Threadsafe Observable集合?

平台: WPF, .NET 4.0, C# 4.0

问题:在Mainwindow.xaml中,我有一个ListBox绑定到Customer集合,该集合当前是一个ObservableCollection <Customer>.

ObservableCollection<Customer> c = new ObservableCollection<Customer>();

此集合可以通过多个源进行更新,如FileSystem,WebService等.

为了允许并行加载Customers,我创建了一个帮助类

public class CustomerManager(ref ObsevableCollection<Customer> cust)

内部为每个客户源生成一个新任务(来自并行扩展库),并将新的Customer实例添加到客户集合对象(由ref传递给它的ctor).

问题是ObservableCollection <T>(或任何集合)不能在UI线程以外的调用中使用并遇到异常:

"NotSupportedException - 这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection."

我试过用了

System.Collections.Concurrent.ConcurrentBag<Customer>

集合但它没有实现INotifyCollectionChanged接口.因此我的WPF UI不会自动更新.

那么,是否有一个集合类可以实现属性/集合更改通知,还允许来自其他非UI线程的调用?

通过我最初的bing /谷歌搜索,没有提供开箱即用.

编辑:我创建了自己的集合,它继承自ConcurrentBag <Customer>,并且还实现了INotifyCollectionChanged接口.但令我惊讶的是,即使在单独的任务中调用它之后,WPF UI也会挂起,直到任务完成.是不应该并行执行任务而不阻止UI线程

提前感谢您的任何建议.

wpf .net-4.0 observablecollection task-parallel-library c#-4.0

21
推荐指数
2
解决办法
2万
查看次数

使用linq对可观察集合进行排序

我有一个可观察的集合,我用linq对它进行排序.一切都很好,但我遇到的问题是如何对实际的可观察集合进行排序?相反,我刚刚结束了与一些IEnumerable的事情,我最终结算的收集和添加的东西回.这不利于性能.有谁知道更好的方法吗?

linq silverlight observablecollection

20
推荐指数
2
解决办法
3万
查看次数

在我的ViewModel中使用Dispatcher是错误的吗?

我正在为我在c#winforms中编写的游戏转换为wpf的聊天解析器,主要是为了更好地处理MVVM和wpf.这是我如何设置项目的故障

查看:现在它只是一个简单的ListBox,ItemSource绑定到我的viewmodels可观察聊天集合

型号:我有多个可以同时登录的角色,每个角色都有一个聊天类.聊天课开始一个后台工作人员从游戏中抓取和下一行聊天,并使用此行触发一个名为IncomingChat的事件.

public event Action<Game.ChatLine> IncomingChat;
Run Code Online (Sandbox Code Playgroud)

我正在使用后台工作人员在我的backgroundworkers progresschaged事件中触发事件,因为当我使用计时器时,我一直遇到线程问题.起初我通过将我的Timer更改为DispatchTimer来纠正这个问题,但是对我来说,在我的模型中使用DispatchTimer似乎并不合适.

ViewModel:由于我有多个字符,我正在创建多个ChatViewModel.我将一个字符传递给ChatViewModels构造函数并订阅Chat事件.我创建了一个ObservableColleciton来在收到此事件时保留我的聊天行.现在,当我尝试将我从聊天事件中收到的行添加到我的observablecollection时,我在viewModel上收到了一个线程问题.

我通过使我的viewmodels传入聊天事件处理程序看起来像这样来解决这个问题

public ObservableCollection<Game.ChatLine) Chat {get; private set;}

void Chat_Incoming(Game.ChatLine line)
{
  App.Current.Dispatcher.Invoke(new Action(delegate
  {
    Chat.Add(line)
  }), null);
}
Run Code Online (Sandbox Code Playgroud)

但这对我来说并不合适.虽然它有效,但在我的viewmodel中使用Dispatcher对我来说似乎不合适.

c# wpf observablecollection mvvm

19
推荐指数
1
解决办法
8748
查看次数

如何复制可观察的集合

我有

Observablecollection<A> aRef = new Observablecollection<A>();
bRef = aRef(); 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,两者都指向相同ObservableCollection...如何制作不同的副本?

wpf copy observablecollection

18
推荐指数
2
解决办法
3万
查看次数

如何在不锁定GUI的情况下将数千个项目添加到绑定的集合中

我有一个设置,可能会有成千上万的项目(想想3000-5000)被添加到ObservableCollection绑定到某个可视界面的项目中.目前,添加它们的过程非常缓慢(大约4秒/ 1000项),当然GUI在此期间没有响应.处理将多个项目一次移动到集合中而不用担心系统锁定的好方法是什么?我看过了,DispatcherTimer但我不确定它是否会提供我需要的一切.

另一个问题 - 我是否可以采取一些措施来加速这些对象的创建,以便将它们添加到集合中并不需要很长时间?目前我使用它们是这样的:Collection.Add(new Item(<params>))事先在后台线程中生成项目会减少将它们添加到显着数量所需的时间吗?

编辑:虚拟化是不可能的.要求指定WrapPanel外观,因此显示实际上是ListBox具有模板化ItemsPanel的显示

编辑2:根据秒表,瓶颈实际上是把物品放进我的ObservableCollection.我将尝试更改该集合类型并进行自己的通知,看看是否会大大加快它的速度.

编辑3:所以答案是在一个地方 - 我通过创建一个继承自的类来解决这个问题(在下面的帮助下)ObservableCollection.这个类做了两件事 - 公开一次添加集合的方法,并添加了抑制CollectionChanged事件的能力.通过这些更改,添加3000个项目所需的时间大约为.4秒(97%的改进).链接详细说明了这些更改的实现.

c# wpf performance observablecollection

18
推荐指数
3
解决办法
1万
查看次数

如何使ObservableCollection线程安全?

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
Run Code Online (Sandbox Code Playgroud)

我正在添加/删除不在UI线程上的ObservableCollection.

我有一个方法名称EnqueueReport添加到colleciton和DequeueReport从集合中删除.

步骤流程如下: -

  1. 1.call EnqueueReport每当请求新报告时
  2. 每隔几秒调用一个方法来检查是否生成了报告(这有一个foreach循环,用于检查ObservableCollection中所有报告的生成状态)
  3. 如果生成报告,则调用DequeueReport

我在C#库中并不多.有人可以指导我吗?

c# observablecollection thread-safety xamarin

18
推荐指数
4
解决办法
2万
查看次数

在CollectionChanged事件期间无法更改ObservableCollection

我有一个CollectionChanged与之相关的事件ObservableCollection.CollectionChanged然后,此事件调用另一个函数,该函数旨在使用原始集合中的项更新另一个集合(相同类型).我已经阅读了" 在CollectionChanged事件期间无法更改ObservableCollection "的其他帖子,我完全理解为什么修改CollectionChanged事件内部的集合以及为什么这会导致循环引用...但在这种特殊情况下我没有修改原始集合,我只是将一个项目添加到一个不相关的集合中.

所以对我的问题......我在做什么有什么不对吗?我没有看到如何将集合中的项目与绑定到另一个集合的事件相关联,然后再次触发事件并创建循环引用(尽管请告诉我,如果我错了).

还有...周围有什么办法吗?我读了几篇帖子,建议在一个单独的线程上运行它,但是当我尝试时,我得到了以下错误.

This type of CollectionView does not support changes to its SourceCollection
from a thread different from the Dispatcher thread.
Run Code Online (Sandbox Code Playgroud)

我真的只是在更好地了解这里发生的事情之后.任何建议将不胜感激.

编辑

请求的简化示例

void originalCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    update(originalCollection);
}

private void update(object parameter)
{
    foreach (var originalCollectionItem in parameter)
        newCollection.Add(originalCollectionItem);
}
Run Code Online (Sandbox Code Playgroud)

.net c# observablecollection

16
推荐指数
1
解决办法
9352
查看次数