Domanda

Ho una casella di riepilogo definito in XAML come:

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

I SelectedDirectories è una struttura negli elenchi DataContext di tipo List<DirectoryInfo>

La classe che è il DataContext per la casella di riepilogo implementa INotifyPropertyChanged. Quando la raccolta cambia gli elementi vengono aggiunti con successo alla lista tuttavia il display non si aggiorna fino a quando forzo la casella di riepilogo di ridisegnare ridimensionando esso.

Tutte le idee perché?

EDIT: INotifyPropertyChanged implementazione

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));
            }
        }
    }
È stato utile?

Soluzione

Prova

ObservableCollection<DirectoryInfo> 

, invece - si sta innescando un aggiornamento di tutta la ListBox per nessun motivo, e che non è necessario per rendere la vostra classe di hosting implementare INotifyPropertyChanged - potrebbe facilmente essere solo una proprietà della finestra. La chiave è quello di non impostare la proprietà ad una nuova istanza. Quindi:

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

Se si finisce per utilizzare quella classe FileScanner, è necessario implementare INotifyCollectionChanged invece -. In questo modo, il ListBox sa cosa aggiungere / rimuovere in modo dinamico

Altri suggerimenti

(vedere Update sotto) . WPF sembra funzionare bene. Ho messo il codice in un nuovo progetto. Gli aggiornamenti casella di riepilogo ogni volta che fa clic sul pulsante di invocare AddDirectory. Non dovrebbe essere necessario alcuna modifica codice più. Il problema sembra essere qualcosa di diverso .. Ci sono più thread nella vostra interfaccia utente?

Non ho avuto il tipo FileScanner. Così ho creato un manichino come segue.

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

Non ci sono cambiamenti nel vostro corso FileScannerPresenter. O il vostro listbox XAML. Ho creato una finestra con una DockPanel contenente il tuo casella di riepilogo, una casella di testo e un pulsante.

Aggiornamento: Paul Betts è giusto. Funziona perché torno un nuovo elenco di volta in volta dalla proprietà Bound. L'associazione dei dati con le liste mi scombina sempre. Con più armeggiare, il modo più semplice per farlo è:

  • Assicurati FileScanner # directory restituiscono un ObservableCollection<DirectoryInfo> (che implementa INotifyCollectionChanged per voi). Cambiare tutte le firme tutta la strada fino a restituire questo tipo, invece di un List<DirectoryInfo>
  • FileScanner e FileScannerPresenter stessi non sono tenuti ad attuare qualsiasi interfaccia INotifyXXX.

    //  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);
         }
      }
    
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top