【问题标题】:WPF threadsave observable collection item change eventWPF 线程安全 observablecollection 项目更改事件
【发布时间】:2012-11-17 10:21:38
【问题描述】:

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

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

我有一个 observablecollection,其中包含一个 downloadInstance 对象,该对象包含一个进度属性。

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

这是我的线程saveobservablecollection 类

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; }
}

一旦实例的属性发生更改(progress++),我如何引发更改事件?

【问题讨论】:

    标签: c# .net wpf observablecollection


    【解决方案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 中得到更新。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-04
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 2022-01-14
        • 2016-05-30
        • 2023-03-08
        相关资源
        最近更新 更多