WPF / C#:将ObservableCollection中项的属性更改更新到ListBox

3

我有一个列表框:

<ListBox x:Name="lbxAF" temsSource="{Binding}">

从这个修改过的可观察集合中获取其数据:

public ObservableCollectionEx<FileItem> folder = new ObservableCollectionEx<FileItem>();

这是在一个使用FileSystemWatcher监视特定文件夹中的文件添加、删除和修改的类内创建的。

ObservableCollection被修改(因此在结尾处加上了Ex),以便我可以从外部线程修改它(代码不是我的,实际上我通过这个网站进行了一些搜索,并找到了它,运行得很好):

    // This is an ObservableCollection extension
    public class ObservableCollectionEx<T> : ObservableCollection<T>
    {
        // Override the vent so this class can access it
        public override event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged;

        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            using (BlockReentrancy())
            {
                System.Collections.Specialized.NotifyCollectionChangedEventHandler eventHanlder = CollectionChanged;
                if (eventHanlder == null)
                    return;

                Delegate[] delegates = eventHanlder.GetInvocationList();

                // Go through the invocation list
                foreach (System.Collections.Specialized.NotifyCollectionChangedEventHandler handler in delegates)
                {
                    DispatcherObject dispatcherObject = handler.Target as DispatcherObject;

                    // If the subscriber is a DispatcherObject and different thread do this:
                    if (dispatcherObject != null && dispatcherObject.CheckAccess() == false)
                    {
                        // Invoke handler in the target dispatcher's thread
                        dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, this, e);
                    }
                    // Else, execute handler as is
                    else
                    {
                        handler(this, e);
                    }
                }
            }
        }
    }

这个集合由以下内容组成:

public class FileItem
{
    public string Name { get; set; }
    public string Path { get; set; }
}

我可以存储文件的名称和路径。删除和添加文件方面,一切都很顺利,ListBox在这两个方面都无误更新了。但是,如果我更改任何一个文件的名称,它就不会更新ListBox。

我该如何通知ListBox文件项属性的更改?我认为ObservableCollection会处理这个问题,但显然它仅在添加或删除FileItem时引发标志,而不是当其内容发生更改时。


你的FileItem没有实现INotifiyPropertyChanged接口...另外你是如何在ViewModel/CodeBehind中更新文件名的? - Nitin
3个回答

12

你的FileItem类应该实现INotifyPropertyChanged。下面是一个简单的可工作的实现。

public class FileItem : INotifyPropertyChanged
{
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set {
            if (_Name != value)
            {
                _Name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    private string _Path;

    public string Path
    {
        get { return _Path; }
        set {
            if (_Path != value)
            {
                _Path = value;
                OnPropertyChanged("Path");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }


}

6

我该如何做呢?我在浏览MSDN文档时感到非常困惑。虽然我是WPF和C#的新手,但让它正常工作是至关重要的。 - B.K.
是的,那就是我在看的那个。当我用我的时候,它没有起作用。实际上它抛出了某种异常。 - B.K.
什么是异常?由于您提到了来自另一个线程的更新,可能会出现跨线程访问异常。 - New Dev
我刚刚查看了AnandMurali提供的代码,我忘记在OnPropertyChanged方法中添加if (PropertyChanged!= null)。 - B.K.

1
尝试这个简单的例子:

public class NotifyObservableCollection<TItem> : ObservableCollection<TItem>
    where TItem : class , INotifyPropertyChanged, new()
{
    #region Fields

    private Action _itemPropertyChanged;

    #endregion

    #region Constructor

    public NotifyObservableCollection(Action itemPropertyChanged)
    {
        _itemPropertyChanged = itemPropertyChanged;
    }

    #endregion

    #region Methods

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (var item in e.NewItems)
            {
                var notifyItem = item as INotifyPropertyChanged;
                if (notifyItem != null)
                {
                    notifyItem.PropertyChanged += ItemPropertyChanged;
                }
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (var item in e.OldItems)
            {
                var notifyItem = item as INotifyPropertyChanged;
                if (notifyItem != null)
                {
                    notifyItem.PropertyChanged -= ItemPropertyChanged;
                }
            }
        }
        base.OnCollectionChanged(e);
    }

    #endregion

    #region Private Methods

    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if(_itemPropertyChanged!=null)
        {
            _itemPropertyChanged();
        }
    }

    #endregion
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接