DataGrid не привязан (XAML + ViewModel + ObservableCollection)

Новичок в стеке WPF + XAML + MVVM, поэтому я уверен, что здесь я делаю что-то базовое, но поиск в Google не помог мне разобраться. Я думаю, что второй набор глаз может помочь.

Настройка

  • У меня есть список объектов с именем FilesToAdd
  • У меня есть DataGrid, связанный с этим списком
  • У меня есть событие перетаскивания, которое запускает код обработки
    • Я подтвердил это работает через Console.WriteLine() выход.

Цель

  • Когда элемент добавляется в список, я бы хотел, чтобы сетка данных обновлялась соответствующей информацией, которая была только что добавлена ​​в список.

Эта проблема

  • Список, кажется, обновляется, но сетка данных никогда не обновляется.

Код

Показаны только соответствующие части.

Класс UploaderViewModel

private ObservableCollection<IAddableFile> _filesToAdd;
public event PropertyChangedEventHandler PropertyChanged;

       public UploaderViewModel()
       {
         _filesToAdd = new ObservableCollection<IAddableFile>();

        }

        protected virtual void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }


        public ObservableCollection<IAddableFile> FilesToAdd 
        {
            get { return _filesToAdd; }
            set
            {
                if (value != _filesToAdd)
                {
                    _filesToAdd = value;
                OnPropertyChanged("FilesToAdd");
                OnPropertyChanged("FilesAreQueued");
                }
            }
        }

        public bool FilesAreQueued
        {
            get { return (FilesToAdd.Count > 0); }
        }

        public void AFileHasBeenAdded(string filepath)
        {
                        var message = String.Format("File dropped: {0}", filepath);
                        Console.WriteLine(message);

            var newFileInfo = new FileInfo(filepath);
            if (newFileInfo.Exists && newFileInfo.Length > 0 && (!FileIsADirectory(newFileInfo))) // only add the file to the ViewModel if it's 
            {
                FilesToAdd.Add(new FileSystemFile(newFileInfo)); //Creating our own type becaause we do additional things with it
                Console.WriteLine(String.Format("File added to list: {0}", newFileInfo.FullName));
            }
        }

XAML Binding

<DataGrid ItemsSource="{Binding FilesToAdd}" Height="100" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="100" AutoGenerateColumns="False" Visibility="{Binding FilesAreQueued, Converter={StaticResource BoolToVisConverter}}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="File Name" Binding="{Binding FileName}"/>
        <DataGridTextColumn Header="Size" Binding="{Binding FileSizeInText}"/>
    </DataGrid.Columns>
</DataGrid>

Что мне не хватает? Я смотрю на шаблон и знаю, что это должно быть что-то простое, чего я не вижу из-за того, что слишком долго смотрю на экран.:)

1 ответ

Решение

Изменить: я подозреваю DataGrid обновления просто отлично, но вы не можете видеть это, потому что FilesAreQueued собственность лжет.

Вам нужно что-то вроде

FilesToAdd.CollectionChanged += (s,e) =>
    OnPropertyChanged("FilesAreQueued");

Поскольку вы хотите сделать это только один раз (если вообще, можете связать с FilesToAdd.Count напрямую), вы действительно должны выбрать readonly поле сбора.


Выглядит хорошо, если DataContext зрения на самом деле это модель представления.

Другая проблема может заключаться в том, что класс не реализует INotifyPropertyChanged (вы можете иметь событие, фактически не реализуя его, используя class : interface), это применимо только в случае перезаписи FilesToAdd недвижимость с новым экземпляром. (Вообще я выставляю коллекции как get только с readonly поле.)

Возможно, вы захотите проверить наличие ошибок привязки (не думайте, что вы получаете их за привязки к нулю DataContext хоть).

(Также я бы порекомендовал сделать OnPropertyChanged поточно-ориентированный, т.е. var handler = <event>; if (handler != null) handler();)

Другие вопросы по тегам