【问题标题】:DataGrid not binding (XAML + ViewModel + ObservableCollection)DataGrid 未绑定(XAML + ViewModel + ObservableCollection)
【发布时间】:2013-08-07 19:18:55
【问题描述】:

WPF + XAML + MVVM 堆栈的新手,所以我确定我在这里做的是一些基本的事情,但谷歌搜索并没有帮助我弄清楚。我认为第二双眼睛可能会有所帮助。

设置

  • 我有一个名为 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 绑定

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

我错过了什么?我一直在研究这种模式,我知道它一定很简单,因为我盯着屏幕太久而看不到。 :)

【问题讨论】:

    标签: wpf xaml mvvm datagrid observablecollection


    【解决方案1】:

    编辑:我怀疑DataGrid 更新正常,但您看不到它,因为FilesAreQueued 属性在撒谎。

    你需要类似的东西

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

    由于您只想这样做一次(如果有的话,可以直接绑定到FilesToAdd.Count),您确实应该选择readonly 集合字段。


    如果视图的 DataContext 实际上是该视图模型,则看起来很好。

    另一个问题可能是该类没有实现INotifyPropertyChanged(您可以在不使用class : interface 实际实现它的情况下拥有该事件),这仅适用于您用新实例覆盖FilesToAdd 属性时。 (一般来说,我将集合公开为get-仅带有readonly 字段。)

    可能想要检查binding errors(尽管不要认为您会得到任何与空DataContext 的绑定)。

    (另外我建议将OnPropertyChanged 设为线程安全,即var handler = &lt;event&gt;; if (handler != null) handler();)

    【讨论】:

    • 好的,我添加了处理程序代码(感谢提示)。我不知道为什么 UI 没有更新。关于数据上下文,我将其设置为DataContext="{StaticResource UploaderViewModel}",然后在窗口的构造函数中创建视图模型类的实例(这样我可以连接依赖项),然后设置Resources["UploaderViewModel"] = uploaderViewModel。其他一切都很好......
    • 哎呀,对不起,我很抱歉,我似乎覆盖了你的编辑(我同时编辑以添加更多代码;正在尝试不同的路线)
    • @SeanKilleen:不用担心,无论如何都是装饰性的,但您刚刚尝试的可能完全不适用 :),您只需要将虚拟机 本身 绑定为ItemsSource.
    • 等等,为了清楚起见,如果我绑定到 ObservableCollection,你是说我什至不需要包含事件处理?
    • @SeanKilleen:你需要监听器,而且这种绑定永远不是双向的。 ItemsSource 不能传播回源,DataGrid 只修改集合本身而不是绑定属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 2021-01-24
    • 2021-08-25
    • 2016-09-13
    • 1970-01-01
    • 2015-01-26
    • 2013-09-07
    相关资源
    最近更新 更多