【问题标题】:C# Chart Axis Labels Not Formatting ProperlyC# 图表轴标签格式不正确
【发布时间】:2017-08-09 01:52:23
【问题描述】:

假设我们有一个访问远程数据库的方法调用,大约需要 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();
}

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

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

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

【问题讨论】:

    标签: c# winforms asynchronous charts async-await


    【解决方案1】:

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

    首先,几个陈述:

    1. XValueType 默认为Auto,如果未明确指定,则在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. 不使用task时,Form_Load的整个body同步执行;当您在图表上调用DataBind 时,它有Auto 对应XValueType,并根据提供DataSource 解析为DateTime

    2. 当您确实使用带睡眠的任务时,Paint 事件会在您初始化 DataSource 之前发生,这会将 XValueType 解析为 Double。之后绑定 DataSource 时,它​​使用 DateTime 的浮点表示。

    如何解决所有这些混乱?方法很多,但都是基于图表值类型:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 2010-10-15
      相关资源
      最近更新 更多