wpf - DataGrid 未绑定(bind)(XAML + ViewModel + ObservableCollection)

标签 wpf xaml mvvm datagrid observablecollection

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/

相关文章:

c# - 为什么我的WPF PasswordBox样式触发器不起作用?

c# - 将函数绑定(bind)到列表框中的文本 block c# WPF

c# - 在 Xamarin.Forms 中使用 MVVM 进行页面导航

c# - MVVM:精简 ViewModel 和丰富模型

c# - 访问后更改项目的背景颜色

c# - 无法从 Listvew.Resources 内部访问 View 模型属性

c# - 带有 TextBlock 和复选框的 XAML ToggleButton

c# - 如何在 C# 中为已在 WPF 中的 XAML 中声明的矩形着色?

c# - 当我将 ItemsPanel 覆盖为 wrappanel 时,为什么列表框需要永远加载?

wpf - 从 StoryBoard 访问 Grid.Columnspan