WPF Listbox pas redessiner
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));
}
}
}
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 œuvreINotifyCollectionChanged
pour vous). Changer toutes les signatures tout le chemin jusqu'à retourner ce type au lieu d'unList<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); } }