WPF + XAML + MVVM 堆栈的新手,所以我确信我在这里做了一些基本的事情,但谷歌搜索并没有帮助我弄清楚。我认为第二双眼睛可能会有所帮助。
设置
- 我有一个名为 FilesToAdd 的对象列表
- 我有一个绑定(bind)到此列表的 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 绑定(bind)
<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>
我错过了什么?我一直在研究这个模式,我知道它一定是一些简单的东西,因为我盯着屏幕太久而看不到。 :)
最佳答案
编辑:我怀疑 DataGrid
更新得很好,但你看不到它,因为 FilesAreQueued
属性(property)在撒谎。
你需要类似的东西
FilesToAdd.CollectionChanged += (s,e) =>
OnPropertyChanged("FilesAreQueued");
由于您只想执行一次(如果有的话,可以直接绑定(bind)到 FilesToAdd.Count
),所以您确实应该选择 readonly
集合字段。
如果 DataContext
看起来不错 View 的实际上就是 View 模型。
另一个问题可能是该类没有实现 INotifyPropertyChanged
(您可以在不使用 class : interface
实际实现该事件的情况下获得该事件),这仅在您覆盖 FilesToAdd
时才适用。具有新实例的属性。 (一般来说,我将集合公开为 get
- 仅带有 readonly
字段。)
可能需要检查 binding errors (不过,我认为您不会得到任何与 null DataContext
的绑定(bind))。
(我还建议将 OnPropertyChanged
设为线程安全,即 var handler = <event>; if (handler != null) handler();
)
关于wpf - DataGrid 未绑定(bind)(XAML + ViewModel + ObservableCollection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18086025/