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

Akgul.Maui.DataGrid不显示属性的问题排查求助

问题:Akgul.Maui.DataGrid 无法显示本地JSON加载的数据

调试确认ObservableCollection<Word>已正确填充数据,但界面仅显示硬编码表头,无内容。使用HttpClient.GetFromJsonAsync获取数据时能正常显示,但本地JSON加载生成集合的方式无效,尝试过数组转换、循环添加、硬编码对象等方法均未解决。


相关代码

GridView 代码

public GridView()
{
    InitializeComponent();
    BindingContext = new BaseViewModel();
}

GetJson 代码

public Dictionary<string, string>? Json
{
    get
    {
        var filePath = JsonFile.FilePath;
        return JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath));
    }
}

public ObservableCollection<Word> LoadWords(Dictionary<string, string> _json)
{
    var result = new ObservableCollection<Word>();
    foreach (var row in _json)
        if (JsonFile.FileName == "English.json" && !string.IsNullOrWhiteSpace(row.Key))
            result.Add(new Word(row.Key)
            {
                English = row.Value,
                Polish = " ",
                ToTranslate = " "
            });
        else if (JsonFile.FileName == "Polish.json" && !string.IsNullOrWhiteSpace(row.Key))
            result.Add(new Word(row.Key)
            {
                Polish = row.Value,
                English = " ",
                ToTranslate = " "
            });
        else if (JsonFile.FileName == "Translation.json" && !string.IsNullOrWhiteSpace(row.Key))
            result.Add(new Word(row.Key)
            {
                ToTranslate = row.Value,
                English = " ",
                Polish = " "
            });
        else if (!string.IsNullOrWhiteSpace(row.Key))
            result.Add(new Word(row.Key)
            {
                ToTranslate = row.Value,
                English = " ",
                Polish = " "
            });
        else
            throw new Exception("Id cannot be null!");

    return result;
}

BaseViewModel 代码

private bool _isRefreshing;

public ObservableCollection<Word> Words { get; set; }
public Command RefreshCommand { get; set; }
public bool IsRefreshing
{
    get => _isRefreshing;
    set
    {
        _isRefreshing = value;
        OnPropertyChanged(nameof(IsRefreshing));
    }
}

public BaseViewModel()
{
    var _getJson = new GetJson();
    Words=_getJson.LoadWords(_getJson.Json!);

    RefreshCommand = new Command(async () =>
    {
        IsRefreshing = true;
        await Task.Delay(3000);
        IsRefreshing = false;
    });
}

#region INotifyPropertyChanged implementation

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string property)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

#endregion INotifyPropertyChanged implementation

DataGrid XAML 代码

<Grid RowDefinitions="*,70">
    <dg:DataGrid Grid.Row="0" ItemsSource="{Binding Words}" SelectionEnabled="True"
                 RowHeight="50" HeaderHeight="30" BorderThickness="2"
                 PullToRefreshCommand="{Binding RefreshCommand}"
                 IsRefreshing="{Binding IsRefreshing}">
        <dg:DataGrid.NoDataView>
            <Label Text="Nothing to see here!" HorizontalOptions="Center" VerticalOptions="Center" />
        </dg:DataGrid.NoDataView>
        <dg:DataGrid.Columns>
            <dg:DataGridColumn Title="Id" PropertyName="Id" HorizontalContentAlignment="Center" />
            <dg:DataGridColumn Title="English" PropertyName="English" HorizontalContentAlignment="Center" />
            <dg:DataGridColumn Title="Polish" PropertyName="Polish" HorizontalContentAlignment="Center" />
            <dg:DataGridColumn Title="Translation" PropertyName="ToTranslate" HorizontalContentAlignment="Center" />
        </dg:DataGrid.Columns>
        <dg:DataGrid.RowsBackgroundColorPalette>
            <dg:PaletteCollection>
                <Color>#F4F4F4</Color>
                <Color>#FFFFFF</Color>
            </dg:PaletteCollection>
        </dg:DataGrid.RowsBackgroundColorPalette>
    </dg:DataGrid>
</Grid>

排查原因与解决方法

核心问题分析

  1. 绑定通知缺失:Words集合在构造函数中直接赋值,未触发PropertyChanged事件。虽然ObservableCollection自身会在内容变化时通知,但初始化时的赋值操作如果没有属性变更通知,UI可能无法感知集合已就绪。
  2. Word类属性无通知:如果Word类的Id、English等属性未实现INotifyPropertyChanged,DataGrid无法正确绑定到属性值。
  3. 同步加载阻塞UI:本地文件读取是同步操作,可能在UI线程阻塞导致绑定流程异常。

具体解决步骤

步骤1:给Word类添加属性变更通知

public class Word : INotifyPropertyChanged
{
    private string _id;
    private string _english;
    private string _polish;
    private string _toTranslate;

    public string Id
    {
        get => _id;
        set
        {
            _id = value;
            OnPropertyChanged(nameof(Id));
        }
    }

    public string English
    {
        get => _english;
        set
        {
            _english = value;
            OnPropertyChanged(nameof(English));
        }
    }

    public string Polish
    {
        get => _polish;
        set
        {
            _polish = value;
            OnPropertyChanged(nameof(Polish));
        }
    }

    public string ToTranslate
    {
        get => _toTranslate;
        set
        {
            _toTranslate = value;
            OnPropertyChanged(nameof(ToTranslate));
        }
    }

    public Word(string id)
    {
        Id = id;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:修改BaseViewModel的Words属性,添加变更通知

private ObservableCollection<Word> _words;
public ObservableCollection<Word> Words
{
    get => _words;
    set
    {
        _words = value;
        OnPropertyChanged(nameof(Words));
    }
}

步骤3:异步加载本地数据(避免UI阻塞)

public BaseViewModel()
{
    RefreshCommand = new Command(async () =>
    {
        IsRefreshing = true;
        await LoadWordsAsync();
        IsRefreshing = false;
    });

    // 初始化时异步加载数据
    _ = LoadWordsAsync();
}

private async Task LoadWordsAsync()
{
    await Task.Run(() =>
    {
        var _getJson = new GetJson();
        Words = _getJson.LoadWords(_getJson.Json!);
    });
}

步骤4:验证属性名匹配

确认DataGridColumn的PropertyName与Word类属性名完全一致(大小写敏感),当前代码已匹配,无需修改。

验证方法

完成修改后重新调试:

  • 确认Words赋值时触发PropertyChanged事件
  • 确认Word类属性赋值时触发通知
  • 检查UI是否正常显示数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:07:05