Pergunta

Eu tenho uma caixa de listagem definido em XAML como:

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

Os SelectedDirectories é uma propriedade nas listas DataContext do tipo List<DirectoryInfo>

A classe que é o datacontext para os implementos de caixa de listagem INotifyPropertyChanged. Quando a coleta muda os itens são adicionados com sucesso à lista no entanto o visor não atualizar até eu forçar a caixa de listagem para redesenhar redimensionando-lo.

Todas as ideias por quê?

EDIT: implementação 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));
            }
        }
    }
Foi útil?

Solução

Tente

ObservableCollection<DirectoryInfo> 

em vez - você está provocando uma atualização de todo o ListBox sem motivo, e você não precisa fazer a sua classe hospedagem implementar INotifyPropertyChanged - poderia facilmente ser apenas uma propriedade da janela. A chave é nunca definir a propriedade para uma nova instância. Assim:

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 você acabar usando essa classe FileScanner, você precisa implementar INotifyCollectionChanged vez -. Dessa forma, o ListBox sabe o que para adicionar / remover dinamicamente

Outras dicas

(veja update abaixo) . WPF parece estar funcionando bem. I colocar seu código em um novo projeto. As atualizações caixa de listagem sempre que clico no botão para invocar AddDirectory. Você não deve precisar de mais alterações no código. O problema parece ser outra coisa .. Existem vários segmentos em sua interface do usuário?

Eu não tenho o tipo FileScanner. Então, eu criei um manequim da seguinte forma.

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

Não muda a sua classe FileScannerPresenter. Ou a sua caixa de listagem XAML. Eu criei uma janela com um DockPanel que contém sua caixa de listagem, uma caixa de texto e um botão.

Update: Paul Betts está certo. Ele funciona porque eu voltar uma nova lista de cada vez a partir da propriedade ligados. Ligação de dados com listas sempre mexe-me. Com mais ajustes, a maneira mais fácil de fazer isso é:

  • Faça FileScanner # Diretórios retornar um ObservableCollection<DirectoryInfo> (que implementa INotifyCollectionChanged para você). Alterar todas as assinaturas todo o caminho até para retornar esse tipo em vez de um List<DirectoryInfo>
  • FileScanner e FileScannerPresenter si não tem que implementar qualquer 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);
         }
      }
    
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top