DataGridViewImageCell 图片加载时不显示,刷新时显示

DataGridViewImageCell Images not displayed on Load, but displayed on Refresh

我的 DataGridView 上有一个 ImageColumn,它根据另一个名为 "HasWarnings" 的隐藏单元格运行。在表单加载事件中,我刷新此 DataGridView,因此对于每一行,如果 HasWarning 为真,则显示警告图像,否则显示成功图像。我的 DataGridView.

顶部还有一个 刷新 按钮

但是,图像没有显示在 Form Load 事件中,我得到了红叉图像。只有当我按下刷新按钮时,它们才会回来。令我惊讶的是,通过单击 Refresh 按钮,会调用与 Load 事件完全相同的函数。下面是在加载事件和单击按钮时调用的刷新方法的代码:

public void RefreshHistory()
{
    pnlOverview.Visible = false;
    pnlNoHistory.Visible = false;
    try
    {
       using (var db = new Entities(cs)
       {
         var linqHistory = db.Histories.Select(h => new 
            { h.Id, h.RunDate, h.HasWarnings }).OrderByDescending(h => h.RunDate).Take(500);
          if (linqHistory.Any())
          {
                dgvHistory.DataSource = linqHistory.ToList();
                dgvHistory.Columns["Id"].Visible = false;
                dgvHistory.Columns["HasWarnings"].Visible = false;
                dgvHistory.Columns["RunDate"].HeaderText = "Date/Time";
                pnlOverview.Visible = true;
                dgvHistory.Rows[0].Selected = true;
                long reportId = Convert.ToInt64(dgvHistory.Rows[0].Cells["Id"].Value);
                SetWarningImages();
                SetReportDetails(reportId);
            }
            else pnlNoHistory.Visible = true;
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message);
    }
}

这是SetWarningImages()方法,将相应的图像分配给DataGridView中的每一行:

private void SetWarningImages()
{
    foreach (DataGridViewRow row in dgvHistory.Rows)
    {
        bool hasWarnings = (bool)row.Cells["HasWarnings"].Value;
        if (hasWarnings)
            ((DataGridViewImageCell)row.Cells["HasWarningsImage"]).Value = 
                                              Properties.Resources.warning16;
        else
            ((DataGridViewImageCell)row.Cells["HasWarningsImage"]).Value =
                                               Properties.Resources.success16;
    }
}

我想知道为什么这段代码不能在 Load 上显示图像(但数据显示正确)但在 button_click 上有效?

N.B. 添加行 dgvHistory.Refresh();dgvHistory.PerformLayout(); 也无济于事。

order of events 有时会迫使您稍微延迟一些事情,直到显示 Form 并且其布局完全完成。

因此,将呼叫转移到 Form.ShownForm.Layout 事件通常会有所帮助。请注意 Form.Layout 可能会发生 more often 比你喜欢的,所以 Form.Shown 可能更可取,除非你想使用标志..

this and this post 中有关于该主题的有趣讨论..