3

リストボックスがあります:

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

この変更された Observable Collection からこれからデータを取得します。

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

これは、FileSystemWatcher を使用して特定のフォルダーでファイルの追加、削除、および変更を監視するクラス内で作成されます。

ObservableCollection が変更されたため (したがって、最後に Ex がありました)、外部スレッドから変更できるようになりました (コードは私のものではありません。実際にこの Web サイトを検索したところ、魅力的に機能することがわかりました)。

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

これにより、ファイルの名前とパスを保存できます。

ファイルの削除と追加に関する限り、すべてがうまく機能し、リストボックスはこれら2つに関して問題なく更新されます...ただし、ファイルの名前を変更しても、リストボックスは更新されません。

FileItem のプロパティの変更をリスト ボックスに通知するにはどうすればよいですか? 私は ObservableCollection がそれを処理すると仮定しましたが、明らかに、その内容が変更されたときではなく、FileItem が追加または削除されたときにのみフラグを立てます。

4

3 に答える 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));
    }


}
于 2013-09-11T02:30:35.273 に答える
5

That's how the ObservableCollection works - it monitors only insertion/deletion/moving of items.

To update the View when each item (or FileItem, in your case) changes, the FileItem must implement INotifyPropertyChanged and fire the appropriate event when you set each property that you want to observe.

Here's an example of how to do this: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

于 2013-09-11T02:25:43.067 に答える
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
}
于 2013-11-05T13:51:18.323 に答える