You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中DataGrid控件无法显示ObservableCollection数据求助

问题分析与解决方案

首先,你的DataGrid无法加载数据的核心原因是Dog类没有暴露公共的可绑定属性——DataGrid需要通过公共属性来读取和显示数据,而你的Dog类里只有私有字段name和number,没有对应的公共getter,绑定系统根本找不到要显示的数据。

一、修复核心问题:完善Dog类

修改Dog类,添加公共属性,并确保INotifyPropertyChanged接口正确生效(初始化时触发不是必须,但养成好习惯能为后续属性变更通知打下基础):

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace PetProject
{
    public class Dog : INotifyPropertyChanged
    {
        private string _name;
        private string _number;

        public event PropertyChangedEventHandler PropertyChanged;

        // 供DataGrid绑定的公共属性
        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        public string Number
        {
            get => _number;
            set
            {
                _number = value;
                OnPropertyChanged();
            }
        }

        public Dog(string name, int number)
        {
            Name = name;
            Number = number.ToString("D4");
        }

        // 简化PropertyChanged触发逻辑,用CallerMemberName自动获取属性名,避免拼写错误
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

二、验证绑定逻辑(现有绑定可行,也可优化)

你的CollectionViewSource绑定到Application.Current.Dogs的写法是正确的,但如果暂时不需要排序/过滤功能,可以直接简化DataGrid的绑定,省去CollectionViewSource:

<!-- 移除Window.Resources中的CollectionViewSource,修改DataGrid绑定 -->
<DataGrid ItemsSource="{Binding Source={x:Static Application.Current}, Path=Dogs}" />

如果后续需要排序、过滤等功能,保留CollectionViewSource的写法即可,只要Dog类有公共属性就能正常显示数据。

三、代码改进建议

  1. 不要在App类中存放业务数据:App类是应用程序入口,适合存放全局配置,业务数据应该放在专门的ViewModel类中,遵循MVVM模式(这是WPF开发的最佳实践,能让代码结构更清晰、易维护)。

  2. ObservableCollection属性设为只读:你的App.Dogs属性的setter是多余的,因为ObservableCollection本身是可变集合(支持Add/Remove操作),不需要替换整个集合。修改为:

public ObservableCollection<Dog> Dogs { get; } = new ObservableCollection<Dog>();

之后在LoadData里直接用Dogs.Add(...)即可,无需初始化私有字段。

  1. 删除无用代码:MainWindow里的DogsDataView变量没有实际用途,可以直接删除。

  2. 显式定义DataGrid列:自动生成列偶尔会出现意外,显式定义列更可控,比如:

<DataGrid ItemsSource="{Binding Source={x:Static Application.Current}, Path=Dogs}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridTextColumn Header="Number" Binding="{Binding Number}" />
    </DataGrid.Columns>
</DataGrid>

做完这些修改后,你的DataGrid应该就能正常显示Johnny和Diamond的数据了。

内容的提问来源于stack exchange,提问作者Ne_Plus_Ultra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:09:49