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

ViewModel更新后DataGrid未同步刷新问题求助

问题解决:DataGrid绑定DataTable后UI不刷新

问题原因

WPF的DataTable对结构变更(增删列)的通知支持有限,即便ViewModel实现了INotifyPropertyChanged,直接修改现有DataTable实例的列/行后,仅调用OnPropertyChanged有时无法触发DataGrid重新生成列或刷新UI。另外你当前代码是直接修改KalenderKerjaTable的现有实例,而非替换为新实例,这会导致绑定系统无法识别有效的变更通知。

解决方案

方案1:替换为新的DataTable实例(推荐)

不要直接修改现有KalenderKerjaTable的列和行,而是创建新的DataTable实例,完成数据填充后再赋值给属性,这样OnPropertyChanged会完全触发绑定更新:

修改GetWorkingCalendar方法中的相关代码:

private async void GetWorkingCalendar()
{
    // 清空HariKerjaTable(若需保留实例则直接清空,否则可直接赋值新实例)
    HariKerjaTable?.Clear();
    // 创建新的KalenderKerjaTable实例,避免修改现有实例
    var newKalenderTable = new DataTable();

    var data = new
    {
        month = Month,
        year = Year,
    };

    string get = await BaseAPI.PostMethod("calendar/select", JsonConvert.SerializeObject(data));
    if (get is not null)
    {
        JObject jsonObject = JObject.Parse(get);
        JToken dataToken = jsonObject["data"];
        HariKerjaTable = dataToken.ToObject<DataTable>();
    }
    else
    {
        MessageBox.Show("Something wrong when retrieving", "Null", MessageBoxButton.OK, MessageBoxImage.Error);
    }

    // await后已回到UI线程,无需手动调用Dispatcher.Invoke
    foreach (DataRow row in HariKerjaTable.Rows)
    {
        DateTime date = DateTime.Parse(row["date_calendar"].ToString());
        Debug.WriteLine(date.ToString("ddd\ndd"));
        if (!newKalenderTable.Columns.Contains(date.ToString("ddd\ndd")))
        {
            newKalenderTable.Columns.Add(date.ToString("ddd\ndd"));
        }
    }

    // 赋值新实例,触发PropertyChanged通知UI更新
    KalenderKerjaTable = newKalenderTable;

    Debug.WriteLine("+++++++++++++++++++++++++++++++");
    foreach (DataColumn column in KalenderKerjaTable.Columns)
    {
        Debug.WriteLine(column.ColumnName);
    }
}

方案2:强制DataGrid刷新(临时方案)

如果必须保留现有DataTable实例,可以在修改完成后强制DataGrid重新绑定:

  1. 给XAML中的DataGrid添加命名:
<Grid Grid.Row="1" Margin="0,5,0,0">
    <DataGrid x:Name="KalenderDataGrid" ItemsSource="{Binding KalenderKerjaTable}" FrozenColumnCount="2" AutoGenerateColumns="True"/>
</Grid>
  1. 在修改完列后执行:
KalenderDataGrid.ItemsSource = null;
KalenderDataGrid.ItemsSource = KalenderKerjaTable;

这种方式不够优雅,仅适合临时场景,不推荐作为长期解决方案。

额外优化点

  • 移除不必要的Application.Current.Dispatcher.Invoke:await异步方法后,默认会回到调用时的同步上下文(UI线程),无需手动切换线程。
  • 初始化HariKerjaTable:在ViewModel构造函数中添加HariKerjaTable = new DataTable();,避免后续调用Rows时出现空引用异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:27:19