Pregunta

Tengo un cuadro de lista se define en XAML como:

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

Los SelectedDirectories es una propiedad en las listas DataContext de tipo List<DirectoryInfo>

La clase que es el DataContext para el cuadro de lista implementa INotifyPropertyChanged. Cuando la colección cambia los elementos se agregan a la lista con éxito sin embargo, la pantalla no se actualiza hasta que fuerzo al cuadro de lista para volver a trazar cambiando el tamaño de la misma.

Cualquier idea por qué?

EDIT: INotifyPropertyChanged aplicación

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));
            }
        }
    }
¿Fue útil?

Solución

Trate

ObservableCollection<DirectoryInfo> 

en lugar - que está provocando una actualización de todo el cuadro de lista sin ninguna razón, y que no es necesario para hacer su clase de alojamiento implementar INotifyPropertyChanged - que fácilmente podría ser simplemente una propiedad de la ventana. La clave es no establecer la propiedad en una nueva instancia. Por lo tanto:

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 terminan usando esa clase FileScanner, es necesario implementar INotifyCollectionChanged lugar -. De esta manera, el ListBox sabe qué añadir / eliminar dinámicamente

Otros consejos

(ver Boletín abajo) . WPF parece estar funcionando bien. Pongo el código en un nuevo proyecto. Las actualizaciones cuadro de lista cada vez que haga clic en el botón para invocar addDirectory. No debería ser necesario más cambios de código. El problema parece ser otra cosa .. ¿Hay múltiples hilos en la interfaz de usuario?

No tuve el tipo FileScanner. Así que creé un maniquí de la siguiente manera.

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

No hay cambios en su clase FileScannerPresenter. O su XAML cuadro de lista. He creado una ventana con un DockPanel que contiene su cuadro de lista, un cuadro de texto y un botón.

Actualización: Paul Betts es correcto. Funciona porque vuelvo una nueva lista cada vez desde la propiedad Bound. vinculante con listas de datos siempre me meta la pata. Con más retoques, la manera más fácil de hacer esto es:

  • Marca FileScanner # correspondientes devuelven un ObservableCollection<DirectoryInfo> (que implementa INotifyCollectionChanged para usted). Cambiar todas las firmas de todo el camino hasta volver este tipo en lugar de un List<DirectoryInfo>
  • FileScanner y FileScannerPresenter sí mismos no tienen que poner en práctica cualquier interfaz 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);
         }
      }
    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top