Question

J'ai un listbox défini en XAML comme:

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

Les SelectedDirectories est une propriété sur les listes DataContext de type List<DirectoryInfo>

La classe qui est le DataContext pour la zone de liste met en œuvre INotifyPropertyChanged. Lorsque la collection change les éléments sont ajoutés avec succès à la liste mais l'affichage ne met pas à jour jusqu'à ce que je force la zone de liste à redessiner en le redimensionnant.

Toutes les idées pourquoi?

EDIT: mise en œuvre INotifyPropertyChanged

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));
            }
        }
    }
Était-ce utile?

La solution

Essayez

ObservableCollection<DirectoryInfo> 

au lieu - vous êtes déclencher une actualisation de l'ensemble ListBox sans raison, et vous ne avez pas besoin de faire de votre classe d'hébergement mettre en œuvre INotifyPropertyChanged - il pourrait facilement être juste une propriété de la fenêtre. La clé est de ne jamais définir la propriété à une nouvelle instance. Donc:

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

Si vous vous retrouvez à l'aide de cette classe FileScanner, vous devez mettre en œuvre à la place INotifyCollectionChanged -. De cette façon, le ListBox sait ce qu'il faut ajouter / supprimer dynamiquement

Autres conseils

(Voir Mise à jour ci-dessous) . WPF semble fonctionner bien. Je mets votre code dans un nouveau projet. Les mises à jour listbox chaque fois que je clique sur le bouton pour appeler addDirectory. Vous ne devriez pas avoir d'autres modifications de code. Le problème semble être autre chose .. Y at-il plusieurs threads dans votre interface utilisateur?

Je n'ai pas eu le type FileScanner. Donc, j'ai créé un mannequin comme suit.

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

Aucun changement à votre classe FileScannerPresenter. Ou votre listbox XAML. J'ai créé une fenêtre avec un DockPanel contenant votre listbox, une zone de texte et un bouton.

Mise à jour: Paul Betts a raison. Cela fonctionne parce que je retourne une nouvelle liste à chaque fois de la propriété liée. La liaison de données avec des listes me salit toujours. Avec plus bricoler, la manière facile de faire est:

  • FileScanner # répertoires renvoient un ObservableCollection<DirectoryInfo> (qui met en œuvre INotifyCollectionChanged pour vous). Changer toutes les signatures tout le chemin jusqu'à retourner ce type au lieu d'un List<DirectoryInfo>
  • FileScanner et FileScannerPresenter eux-mêmes ne doivent pas mettre en œuvre aucune interface 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);
         }
      }
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top