WPF线程安​​全observablecollection项目更改事件

时间:2012-11-17 10:21:38

标签: c# .net wpf observablecollection

我的应用程序是一个基本的下载应用程序,允许用户从彼此下载文件(一个非常基本的kazaa: - ))

每次下载我都会显示一个进度条,我希望它根据实际的下载进度进行更新。

我有一个observablecollection,它包含一个包含progress属性的downloadInstance对象。

一旦我更新了progress属性,observablecollection更改事件可能没有被触发,并且进度条没有任何可视进展。

这是我的threadsaveobservablecollection类

public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
    public override event NotifyCollectionChangedEventHandler CollectionChanged;

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
        if (CollectionChanged != null)
            foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
            {
                DispatcherObject dispObj = nh.Target as DispatcherObject;
                if (dispObj != null)
                {
                    Dispatcher dispatcher = dispObj.Dispatcher;
                    if (dispatcher != null && !dispatcher.CheckAccess())
                    {
                        dispatcher.BeginInvoke(
                            (Action)(() => nh.Invoke(this,
                                new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
                            DispatcherPriority.DataBind);
                        continue;
                    }
                }
                nh.Invoke(this, e);
            }
    }

}

这是初始化过程

uploadActiveInstances = new ThreadSafeObservableCollection<instance>();
instance newInstance = new instance() { File = file, User = user };
uploadActiveInstances.Add(newInstance);

最后这是我的实例类

public class instance
{
    public FileShareUser User { get; set; }
    public SharedFile File { get; set; }
    public int Progress { get; set; }
}

如果实例的属性发生变化,我怎样才能提出变更事件?(进展++)?

2 个答案:

答案 0 :(得分:1)

ObservableCollection将在IT更改(例如添加/删除项目)时引发事件,但在其保留的项目发生更改时不会引发事件。

要在商品更改时举起活动,您的instance课程必须实施INotifyPropertyChanged界面。

例如:

public class instance : INotifyPropertyChanged
{
    private int progress;
    public int Progress 
    {
        get { return progress; }
        set
        {
            if (progress != value)
            {
                progress = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
                }
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    /* Do the same with the remaining properties */
    public string User { get; set; }
    public string File { get; set; }

}

现在,您将看到,当您更改进度时,它将在UI中更新 在上面的代码中,由于我没有为UserFile引发PropertyChanged事件,因此当您更改它们时,它们不会在UI中更新。

答案 1 :(得分:0)

Observablecollection仅在添加或删除项目时更新可视树 这就是为什么当您更改项目值时,它不会被重新渲染。

将Progress属性更改为依赖项属性并绑定进度条“Value”属性 或实现INotifyPropertyChanged接口