C# 图表轴标签格式不正确

标签 c# winforms asynchronous charts async-await

假设我们有一个访问远程数据库的方法调用,大约需要 1 秒完成并返回一个 DataTable(下面模拟):

DataTable GetData()
{
    Thread.Sleep(1000); // simulated delay

    var dt = new DataTable("DataTable");
    dt.Columns.Add("DateTime", typeof(DateTime));
    dt.Columns.Add("Value", typeof(double));

    var rand = new Random();
    var date = new DateTime(2016, 1, 1);
    for (int i = 0; i < 1000; i++)
    {
        dt.Rows.Add(date, rand.NextDouble() * 100);

        date = date.AddHours(12);
    }

    return dt;
}

从此方法返回的 DataTable 用于用单行系列填充 Chart。为什么此代码显示正确、格式正确的 DateTime X 轴标签:

async void MainForm_Load(object sender, EventArgs e)
{
    var data = GetData();
    chart.DataSource = data;
    chart.DataBind();
}

Chart with DateTime X-Axis

并且这段代码显示了不正确的、未格式化的 X 轴标签?

async void MainForm_Load(object sender, EventArgs e)
{
    var data = await Task.Run(() => GetData());
    chart.DataSource = data;
    chart.DataBind();
}

Chart with broken X-Axis

请注意,删除 Thread.Sleep() 调用也可以解决此问题,即使使用第二个版本也是如此。

最佳答案

答案就在chart.Series[0].XValueType

首先,声明几个:

  1. XValueTypeAuto默认情况下,如果未明确指定,则在 Paint 之前的某处解析为特定类型事件。

    不是很明显,我是通过反编译源找到的;如果你确实想关注我的研究,这里有一些里程碑:

    • Chart构造函数:

      this._dataManager.Initialize();

    • DataManager.Initialize :

      chartImage.BeforePaint += ChartPicture_BeforePaint

    • DataManager.ChartPicture_BeforePaint
    • DataManager.PrepareData
    • Series.PrepareData =>

      if (this._xValueType == ChartValueType.Auto) { this._xValueType = ChartValueType.Double;

  2. DataBind将尝试解决 Auto到基于 DataSource 的特定类型.如果它不是 Auto , 它不会考虑 DataSource 中的数据类型.

好的,那么您的示例中发生了什么:

  1. 当你不使用任务时,Form_Load的整体同步执行;当你调用DataBind在图表上,它有 Auto对于 XValueType并解析为DateTime基于提供DataSource .

  2. 当你在 sleep 中使用任务时,Paint事件发生在你初始化之前 DataSource ,它解决了 XValueTypeDouble .之后绑定(bind) DataSource 时,它​​使用 DateTime 的浮点表示.

如何解决所有这些乱七八糟的问题?很多方法,但都是基于图表值类型:

  • Form_Load 中明确指定值类型
  • 删除系列并恰好在 DataBind 之前添加新系列
  • DataBind 之前明确指定值类型
  • ...

关于C# 图表轴标签格式不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42858654/

相关文章:

c# - ASP.NET在运行时显示和隐藏图像

c# - 从文件中修剪函数,以便仅剩下的字符是函数名称和参数

c# - 添加新项目时防止 ListView 自动水平滚动

javascript - Chrome 扩展程序 : query tabs async

javascript - Async Await 是否违反了 sails 1.0 的 MVC?

c# - "addition"和 "bitwise addition"之间有区别吗?

c# - 如何更新 Entity Framework 中的相关实体

C# 从 Windows 窗体中的 TabPages 中删除填充

c# - 使用滚动条获取光标在面板上的位置

scala - Play Framework 异步操作 : Future recover not working