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