Вопрос

У меня есть список, определенный в XAML как:

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

SelectedDirectories — это свойство в списках DataContext типа List<DirectoryInfo>

Класс, который является контекстом данных для списка, реализует INotifyPropertyChanged.Когда коллекция изменяется, элементы успешно добавляются в список, однако отображение не обновляется, пока я не заставлю список перерисоваться, изменив его размер.

Есть идеи, почему?

РЕДАКТИРОВАТЬ:Реализация 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));
            }
        }
    }
Это было полезно?

Решение

Пытаться

ObservableCollection<DirectoryInfo> 

вместо этого вы запускаете обновление всего ListBox без причины, и вам не нужно, чтобы ваш хост-класс реализовывал INotifyPropertyChanged — это легко может быть просто свойством окна.Главное — никогда не устанавливать свойство для нового экземпляра.Так:

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

Если вы в конечном итоге будете использовать этот класс FileScanner, вам необходимо вместо этого реализовать INotifyCollectionChanged - таким образом ListBox будет знать, что добавлять/удалять динамически.

Другие советы

(См. Обновление ниже).WPF, кажется, работает нормально.Я поместил ваш код в новый проект. Список обновляется всякий раз, когда я нажимаю кнопку для вызова AddDirectory.Вам больше не потребуется вносить изменения в код. Проблема видимо в другом..Есть ли в вашем пользовательском интерфейсе несколько потоков?

У меня не было типа FileScanner.Поэтому я создал манекен следующим образом.

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

Никаких изменений в вашем классе FileScannerPresenter.Или ваш список XAML.Я создал окно с DockPanel, содержащим ваш список, текстовое поле и кнопку.

Обновлять: Пол Беттс прав.Это работает, потому что я каждый раз возвращаю новый список из свойства Bound.Привязка данных со списками всегда меня смущает.Если повозиться, простой способ сделать это:

  • Заставить FileScanner#Directories возвращать ObservableCollection<DirectoryInfo> (который реализует INotifyCollectionChanged для тебя).Измените все подписи до конца, чтобы они возвращали этот тип вместо List<DirectoryInfo>
  • FileScanner и FileScannerPresenter не обязательно должны реализовывать какой-либо интерфейс 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);
         }
      }
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top