Frage

I'm binding observablecColletion in ViewModel to a combobox in View (using MVVM Caliburn.Micro). The obsevableColletion is getting its items from a string array which gets the file names in a directory. So my question is: How can i make the combobox to update automatially when i add or delete a file in the directory?

Here is my code: ViewModel

private ObservableCollection<string> _combodata;
Public ObservableCollection<string> ComboData
{
    get
   {
      string[] files = Directory.GetFiles("C:\\Documents");
      _combodata = new ObservableCollection<string>(files);
      return _combodata;
   }
   set
   {
       _combodata = value;
       NotifyOfPropertyChange(() => ComboData);
   }
}

View:

<ComboBox x:name = "ComboData" ......../>
War es hilfreich?

Lösung

Here's a view model that does what you want. It uses a FileSystemWatcher to detect changes in the file system. It uses Dispatcher to marshal the FileSystemWatcher events back to the UI thread (you don't want to change an ObservableCollection on background threads). You should call Dispose of this view model when you are done with it.

public class ViewModel : IDisposable
{
    // Constructor.
    public ViewModel()
    {
        // capture dispatcher for current thread (model should be created on UI thread)
        _dispatcher = Dispatcher.CurrentDispatcher;

        // start watching file system
        _watcher = new FileSystemWatcher("C:\\Documents");
        _watcher.Created += Watcher_Created;
        _watcher.Deleted += Watcher_Deleted;
        _watcher.Renamed += Watcher_Renamed;
        _watcher.EnableRaisingEvents = true;

        // initialize combo data
        _comboData = new ObservableCollection<string>(Directory.GetFiles(_watcher.Path));
        ComboData = new ReadOnlyObservableCollection<string>(_comboData);
    }

    // Disposal
    public void Dispose()
    {
        // dispose of the watcher
        _watcher.Dispose();
    }

    // the dispatcher is used to marshal events to the UI thread
    private readonly Dispatcher _dispatcher;

    // the watcher is used to track file system changes
    private readonly FileSystemWatcher _watcher;

    // the backing field for the ComboData property
    private readonly ObservableCollection<string> _comboData;

    // the ComboData property should be bound to the UI
    public ReadOnlyObservableCollection<string> ComboData { get; private set; }

    // called on a background thread when a file/directory is created
    private void Watcher_Created(object sender, FileSystemEventArgs e)
    {
        _dispatcher.BeginInvoke(new Action(() => _comboData.Add(e.FullPath)));
    }

    // called on a background thread when a file/directory is deleted
    private void Watcher_Deleted(object sender, FileSystemEventArgs e)
    {
        _dispatcher.BeginInvoke(new Action(() => _comboData.Remove(e.FullPath)));
    }

    // called on a background thread when a file/directory is renamed
    private void Watcher_Renamed(object sender, RenamedEventArgs e)
    {
        _dispatcher.BeginInvoke(new Action(() =>
            {
                _comboData.Remove(e.OldFullPath);
                _comboData.Add(e.FullPath);
            }));
    }
}

Andere Tipps

You've to bind an event to listen to changes in the directory you're adding/removing stuff from. Just setup FileSystemWatcher and add/remove stuff from your observable collection as it alerts you.

Example at http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top