Frage

Ich habe eine Listbox definiert in XAML als:

<ListBox x:Name="directoryList"
                 MinHeight="100" 
                 Grid.Row="0"
                 ItemsSource="{Binding Path=SelectedDirectories}"/>

Die SelectedDirectories ist eine Eigenschaft auf den Listen Datacontext vom Typ List<DirectoryInfo>

Die Klasse, die die Datacontext für das Listenfeld ist implementiert INotifyPropertyChanged. Wenn die Sammlung verändert werden die Elemente erfolgreich in die Liste aufgenommen aber die Anzeige nicht aktualisiert, bis ich die Listbox erzwingen, indem es die Größenänderung neu zu zeichnen.

Irgendwelche Ideen, warum?

EDIT: INotifyPropertyChanged Umsetzung

public class FileScannerPresenter : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private FileScanner _FileScanner;

        public FileScannerPresenter()
        {
            this._FileScanner = new FileScanner();
        }

        public List<DirectoryInfo> SelectedDirectories
        {
            get
            {
                return _FileScanner.Directories;
            }
        }

        public void AddDirectory(string path)
        {
            this._FileScanner.AddDirectory(path);
            OnPropertyChanged("SelectedDirectories");
        }

        public void OnPropertyChanged(string property)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }
War es hilfreich?

Lösung

Versuchen

ObservableCollection<DirectoryInfo> 

statt - Sie Auslösen einer Aktualisierung des gesamten ListBox ohne Grund, und Sie brauchen nicht Ihr Hosting-Klasse machen INotifyPropertyChanged implementieren - es könnte leicht nur eine Eigenschaft des Fensters sein. Der Schlüssel ist, nie die Eigenschaft auf eine neue Instanz festgelegt. Also:

class SomeWindow : Window {
    public ObservableCollection<DirectoryInfo> SelectedDirectories {get; private set;}

    SomeWindow() { SelectedDirectories = new ObservableCollection<DirectoryInfo>(); }

    public void AddDirectory(string path) {
        SelectedDirectories.Add(new DirectoryInfo(path));
    }
}

Wenn Sie die Filescanner-Klasse am Ende, Sie müssen stattdessen INotifyCollectionChanged implementieren -. Auf diese Weise die List-Box weiß, was dynamisch hinzufügen / entfernen

Andere Tipps

(Siehe unten Aktualisieren) . WPF scheint in Ordnung zu arbeiten. Ich habe den Code in ein neues Projekt. Die listbox-Updates, wenn ich auf die Schaltfläche klicken, um AddDirectory aufzurufen. Sie sollten keine weiteren Änderungen am Code benötigen. Das Problem scheint, etwas anderes zu sein .. Gibt es mehrere Threads in Ihrer Benutzeroberfläche?

Ich habe nicht den Filescanner Typ. Also habe ich einen Dummy wie folgt.

public class FileScanner
   {
      string _path;
      public FileScanner()
      {     _path = @"c:\";      }
      public List<DirectoryInfo> Directories
      {
         get
         {
            return Directory.GetDirectories(_path).Select(path => new DirectoryInfo(path)).ToList();
         }
      }

      internal void AddDirectory(string path)
      {         _path = path;      }
   }

Keine Änderungen an Ihrer FileScannerPresenter Klasse. Oder Ihr listbox XAML. Ich habe ein Fenster mit einem DockPanel Ihre Listbox enthält, ein Textfeld und eine Schaltfläche.

Update: Paul Betts richtig ist. Es funktioniert, weil ich eine neue Liste jedes Mal von der Bound-Eigenschaft zurück. Datenbindung mit Listen vermasselt mich immer auf. Mit mehr Bastelei, die einfache Möglichkeit, dies zu tun ist:

  • Erstellen Sie Filescanner # Verzeichnisse geben eine ObservableCollection<DirectoryInfo> (die INotifyCollectionChanged für Sie implementiert). Ändern Sie alle Unterschriften den ganzen Weg bis zu dieser Art Rückkehr anstelle eines List<DirectoryInfo>
  • Filescanner und FileScannerPresenter selbst haben keine INotifyXXX Schnittstelle zu implementieren.

    //  in FileScanner class def         
      public ObservableCollection<DirectoryInfo> Directories
      {
         get
         {  return _DirList;  }
      }
      internal void AddDirectory(string path)
      {
         _path = path;
         //var newItems = Directory.GetDirectories(_path).Select(thePath => new DirectoryInfo(thePath)).ToList();
         //_DirList.Concat( newItems );  -- doesn't work for some reason.
         foreach (var info in Directory.GetDirectories(_path).Select(thePath => new DirectoryInfo(thePath)).ToList())
         {
            _DirList.Add(info);
         }
      }
    
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top