C# WPF线程保存可观察的集合项更改事件

C# WPF线程保存可观察的集合项更改事件,c#,.net,wpf,observablecollection,C#,.net,Wpf,Observablecollection,我的应用程序是一个基本的下载应用程序,允许用户互相下载文件(一个非常基本的kazaa:-) 每次下载我都会显示一个进度条,我希望它能根据实际下载进度进行更新 我有一个observablecollection,它包含一个downloadInstance对象,该对象包含一个progress属性 一旦我更新了progress属性,ObservaleCollection更改事件可能不会被触发,progressbar将保持没有任何可视进度 这是我的threadsaveobservablecollectio

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

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

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

一旦我更新了progress属性,ObservaleCollection更改事件可能不会被触发,progressbar将保持没有任何可视进度

这是我的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);
            }
    }

}

当实例的属性更改(progress++)时,如何引发更改事件?

ObservableCollection在更改(例如,添加/删除项)时会引发事件,但在其持有的项更改时不会

要在项目更改时引发事件,您的
实例
类必须实现
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中得到更新。

在上面的代码中,由于我没有为
用户
文件
引发PropertyChanged事件,因此当您更改它们时,它们不会在UI中得到更新。

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

将进度属性更改为依赖项属性,并绑定进度栏“值”属性 或者实现INotifyPropertyChanged接口

public class instance
{
    public FileShareUser User { get; set; }
    public SharedFile File { get; set; }
    public int Progress { get; set; }
}
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; }

}