如何通过将 DateTime 正确转换为 Double,将 DateTime 锚定到 ASP 柱形图上的 X 坐标?
How can I anchor a DateTime to the X coordinate on an ASP Column Chart by properly converting it to a Double?
我正在尝试将 DateTime 对象锚定到 ASP 柱形图的 X 坐标,以便我可以在图表初始化时在柱上显示线条注释。我知道它需要是 Double 才能工作,我尝试使用 DateTime.Now.ToOADate() 以及 ToDouble() 和 DateTime.Ticks 属性,但是 none 他们中有工作。
这是我的代码 (MainForm.aspx.cs):
void getChartData()
{
String ConString = ConfigurationManager.ConnectionStrings["cs"].ConnectionString;
using (SqlConnection connection = new SqlConnection(ConString))
{
String SQLText = "select AvailDate,MW from MWAvailability2 where UnitName = @UnitName and Station = @StationName and AvailDate between @AvailFrom and @AvailTo";
SqlCommand cmd = new SqlCommand(SQLText, connection);
connection.Open();
cmd.Parameters.AddWithValue("@UnitName", ddUnit.SelectedValue);
cmd.Parameters.AddWithValue("@StationName", ddStation.SelectedValue);
if (TextBoxFrom.Text.Length > 0)
{
cmd.Parameters.AddWithValue("@AvailFrom", TextBoxFrom.Text);
}
else
{
cmd.Parameters.AddWithValue("@AvailFrom", "01-01-1900");
}
if (TextBoxTo.Text.Length > 0)
{
cmd.Parameters.AddWithValue("@AvailTo", TextBoxTo.Text);
}
else
{
cmd.Parameters.AddWithValue("@AvailTo", "01-01-2050");
}
if (TextBoxFrom.Text.Length > 0 && TextBoxTo.Text.Length > 0) // Text in from, text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: " + TextBoxFrom.Text + " To: " + TextBoxTo.Text;
}
else if (TextBoxFrom.Text.Length > 0 && TextBoxTo.Text.Length == 0) // Text in from, no text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: " + TextBoxFrom.Text + " To: 01/01/2050";
}
else if (TextBoxFrom.Text.Length == 0 && TextBoxTo.Text.Length > 0) // No text in from, text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: 01/01/1900 " + " To: " + TextBoxTo.Text;
}
else if (TextBoxFrom.Text.Length == 0 && TextBoxTo.Text.Length == 0) // No text in from, no text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: 01/01/1900 To: 01/01/2050";
}
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Series series = ColumnChart.Series["Series1"];
if (reader.HasRows)
{
series.Points.AddXY(reader["AvailDate"].ToString(), reader["MW"]);
TextAnnotation ta = new TextAnnotation();
ta.AnchorX = Convert.ToDouble(reader["AvailDate"]); // problem
ta.AnchorY = Convert.ToDouble(reader["MW"]);
ta.Text = "Station A";
ColumnChart.Annotations.Add(ta);
}
else
{
Console.WriteLine("No rows found.");
}
}
}
}
当应该将文本注释锚定到 X 坐标的行显示 ta.AnchorX = Convert.ToDouble(reader["AvailDate"]);
时,我收到一条错误消息显示 "Invalid cast from 'DateTime' to 'Double'." 当我将其更改为 ta.AnchorX = Convert.ToDouble(reader["AvailDate"].ToString());
时,错误告诉我 "Input string was not in a correct format."
如果有帮助,这里是 HomePage.aspx.cs 的代码,其中进行此转换显然不那么复杂:
void getChartData()
{
DataSet ds = new DataSet();
// Read the data from XML file into DataSet
ds.ReadXml(Server.MapPath("~/MWAvailability2.xml"));
// Specify the column that contains values for X-AXIS
ColumnChart.Series["Series1"].XValueMember = "AvailDate";
// Specify the column that contains values for Y-AXIS
ColumnChart.Series["Series1"].YValueMembers = "MW";
// Annotations?
TextAnnotation ta = new TextAnnotation();
var xv = Convert.ToDouble("AvailDate");
var yv = Convert.ToDouble("MW");
ta.AnchorX = xv;
ta.AnchorY = yv;
ta.Text = "Station A";
ColumnChart.Annotations.Add(ta);
// Set DataSet as the DataSource for the Chart control
ColumnChart.DataSource = ds;
// Finally call DataBind
ColumnChart.DataBind();
}
我认为错误很可能与 SQL reader 对象有关,但我不确定。我在这里尝试了类似问题的其他解决方案,其中一些已在上面列出,但其中 none 似乎适用于我的情况。
我很乐意提供我可能遗漏的任何其他信息,这些信息可能有助于更好地解释我的情况。任何可以帮助我解决这个问题的意见或建议将不胜感激。提前致谢!
我将尝试主要关注您的问题行,它应该会引导您朝着正确的方向前进...
ta.AnchorX = Convert.ToDouble(reader["AvailDate"]); // problem
这里的问题是您没有提供 DateTime
值。 SqlReader
class 在使用索引器时总是返回对象,这意味着您实际上是在调用构造函数 Convert.ToDouble(object)
而不是 Convert.ToDouble(DateTime)
。 Convert
class 正在抑制编译器错误,因为存在方法调用的匹配项,但不是您期望的匹配项。您可以通过尝试直接使用 reader["AvailDate"]
分配变量 AnchorX
来确认这一点。它会告诉您强制转换无效,因为如果没有显式强制转换,对象不能存储在更派生的类型中。如果您将 ToString()
附加到 reader(["AvailDate"])
,这同样会调用 Convert.ToDouble(String)
。如果存储在 SQL 数据库中的类型确实是 Date
或 DateTime
的类型,那么您可以简单地指定一个转换。
试试这个:
ta.AnchorX = Convert.ToDouble((DateTime)reader["AvailDate"]); // solution?
更新
@Quantic 提醒我仍然抛出 InvalidCastException,而转换仍然是必要的,因为我最初的假设是它将在运行时失败。进一步检查 MSDN Convert.ToDouble(DateTime) 不受支持,将失败:
Return Value
Type: System.Double
This conversion is not supported. No value is returned.
https://msdn.microsoft.com/en-us/library/hfdd1sd9(v=vs.110).aspx
正确的调用确实是...
ta.AnchorX = ((DateTime)reader["AvailDate"]).ToOADate();
我正在尝试将 DateTime 对象锚定到 ASP 柱形图的 X 坐标,以便我可以在图表初始化时在柱上显示线条注释。我知道它需要是 Double 才能工作,我尝试使用 DateTime.Now.ToOADate() 以及 ToDouble() 和 DateTime.Ticks 属性,但是 none 他们中有工作。
这是我的代码 (MainForm.aspx.cs):
void getChartData()
{
String ConString = ConfigurationManager.ConnectionStrings["cs"].ConnectionString;
using (SqlConnection connection = new SqlConnection(ConString))
{
String SQLText = "select AvailDate,MW from MWAvailability2 where UnitName = @UnitName and Station = @StationName and AvailDate between @AvailFrom and @AvailTo";
SqlCommand cmd = new SqlCommand(SQLText, connection);
connection.Open();
cmd.Parameters.AddWithValue("@UnitName", ddUnit.SelectedValue);
cmd.Parameters.AddWithValue("@StationName", ddStation.SelectedValue);
if (TextBoxFrom.Text.Length > 0)
{
cmd.Parameters.AddWithValue("@AvailFrom", TextBoxFrom.Text);
}
else
{
cmd.Parameters.AddWithValue("@AvailFrom", "01-01-1900");
}
if (TextBoxTo.Text.Length > 0)
{
cmd.Parameters.AddWithValue("@AvailTo", TextBoxTo.Text);
}
else
{
cmd.Parameters.AddWithValue("@AvailTo", "01-01-2050");
}
if (TextBoxFrom.Text.Length > 0 && TextBoxTo.Text.Length > 0) // Text in from, text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: " + TextBoxFrom.Text + " To: " + TextBoxTo.Text;
}
else if (TextBoxFrom.Text.Length > 0 && TextBoxTo.Text.Length == 0) // Text in from, no text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: " + TextBoxFrom.Text + " To: 01/01/2050";
}
else if (TextBoxFrom.Text.Length == 0 && TextBoxTo.Text.Length > 0) // No text in from, text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: 01/01/1900 " + " To: " + TextBoxTo.Text;
}
else if (TextBoxFrom.Text.Length == 0 && TextBoxTo.Text.Length == 0) // No text in from, no text in to
{
chartTitle.Text = "Station " + ddStation.SelectedValue + " " + ddUnit.SelectedValue + " From: 01/01/1900 To: 01/01/2050";
}
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Series series = ColumnChart.Series["Series1"];
if (reader.HasRows)
{
series.Points.AddXY(reader["AvailDate"].ToString(), reader["MW"]);
TextAnnotation ta = new TextAnnotation();
ta.AnchorX = Convert.ToDouble(reader["AvailDate"]); // problem
ta.AnchorY = Convert.ToDouble(reader["MW"]);
ta.Text = "Station A";
ColumnChart.Annotations.Add(ta);
}
else
{
Console.WriteLine("No rows found.");
}
}
}
}
当应该将文本注释锚定到 X 坐标的行显示 ta.AnchorX = Convert.ToDouble(reader["AvailDate"]);
时,我收到一条错误消息显示 "Invalid cast from 'DateTime' to 'Double'." 当我将其更改为 ta.AnchorX = Convert.ToDouble(reader["AvailDate"].ToString());
时,错误告诉我 "Input string was not in a correct format."
如果有帮助,这里是 HomePage.aspx.cs 的代码,其中进行此转换显然不那么复杂:
void getChartData()
{
DataSet ds = new DataSet();
// Read the data from XML file into DataSet
ds.ReadXml(Server.MapPath("~/MWAvailability2.xml"));
// Specify the column that contains values for X-AXIS
ColumnChart.Series["Series1"].XValueMember = "AvailDate";
// Specify the column that contains values for Y-AXIS
ColumnChart.Series["Series1"].YValueMembers = "MW";
// Annotations?
TextAnnotation ta = new TextAnnotation();
var xv = Convert.ToDouble("AvailDate");
var yv = Convert.ToDouble("MW");
ta.AnchorX = xv;
ta.AnchorY = yv;
ta.Text = "Station A";
ColumnChart.Annotations.Add(ta);
// Set DataSet as the DataSource for the Chart control
ColumnChart.DataSource = ds;
// Finally call DataBind
ColumnChart.DataBind();
}
我认为错误很可能与 SQL reader 对象有关,但我不确定。我在这里尝试了类似问题的其他解决方案,其中一些已在上面列出,但其中 none 似乎适用于我的情况。
我很乐意提供我可能遗漏的任何其他信息,这些信息可能有助于更好地解释我的情况。任何可以帮助我解决这个问题的意见或建议将不胜感激。提前致谢!
我将尝试主要关注您的问题行,它应该会引导您朝着正确的方向前进...
ta.AnchorX = Convert.ToDouble(reader["AvailDate"]); // problem
这里的问题是您没有提供 DateTime
值。 SqlReader
class 在使用索引器时总是返回对象,这意味着您实际上是在调用构造函数 Convert.ToDouble(object)
而不是 Convert.ToDouble(DateTime)
。 Convert
class 正在抑制编译器错误,因为存在方法调用的匹配项,但不是您期望的匹配项。您可以通过尝试直接使用 reader["AvailDate"]
分配变量 AnchorX
来确认这一点。它会告诉您强制转换无效,因为如果没有显式强制转换,对象不能存储在更派生的类型中。如果您将 ToString()
附加到 reader(["AvailDate"])
,这同样会调用 Convert.ToDouble(String)
。如果存储在 SQL 数据库中的类型确实是 Date
或 DateTime
的类型,那么您可以简单地指定一个转换。
试试这个:
ta.AnchorX = Convert.ToDouble((DateTime)reader["AvailDate"]); // solution?
更新
@Quantic 提醒我仍然抛出 InvalidCastException,而转换仍然是必要的,因为我最初的假设是它将在运行时失败。进一步检查 MSDN Convert.ToDouble(DateTime) 不受支持,将失败:
Return Value Type: System.Double This conversion is not supported. No value is returned.
https://msdn.microsoft.com/en-us/library/hfdd1sd9(v=vs.110).aspx
正确的调用确实是...
ta.AnchorX = ((DateTime)reader["AvailDate"]).ToOADate();