[英]C# Using data from DataGridView in a Chart
I have code that generates data in the DataGridView and I want to also push this to a chart from the same button click. 我有在DataGridView中生成数据的代码,我也想通过单击同一按钮将其推送到图表。
Process: 处理:
Text is put into a text box myInputBox
then the button processButton
is pressed to split the text up and output it to the DataGridView myOutputDGV
the button has the following code: 将文本放入文本框
myInputBox
然后按下按钮processButton
拆分文本并将其输出到DataGridView myOutputDGV
该按钮具有以下代码:
private void processButton_Click(object sender, EventArgs e)
{
List<string> mySplit = new List<string>(myInputBox.Text.Split(new string[] { "XN" }, StringSplitOptions.None));
DataGridViewTextBoxColumn myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Line";
myOutputGrid.Name = "Line";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Section";
myOutputGrid.Name = "Section";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Range";
myOutputGrid.Name = "Range";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Total";
myOutputGrid.Name = "Total";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
foreach (string item in mySplit)
{
myOutputDGV.Rows.Add(item.Trim(),
item.Split(new string[] { "(cost=" }, StringSplitOptions.None).First(),
Regex.Match(item, @"cost=(.+?) rows").Groups[1].Value,
Regex.Match(item, @"cost=(.+?)\.\.").Groups[1].Value,
}
}
I want to populate my chart myChart
with the values from column[1] (Line) on the X axis and column[3] (Total) on the Y axis. 我想用来自X轴上的column [1](直线)和Y轴上的column [3](总计)的值填充图表
myChart
。
EDIT: 编辑:
I have tried adding the following code in the button processButton
click code but the chart isn't populated: 我尝试在按钮
processButton
单击代码中添加以下代码,但未填充图表:
ChartArea chartArea1 = new ChartArea();
chartArea1.AxisX.MajorGrid.LineColor = Color.LightGray;
chartArea1.AxisY.MajorGrid.LineColor = Color.LightGray;
chartArea1.AxisX.LabelStyle.Font = new Font("Consolas", 8);
chartArea1.AxisY.LabelStyle.Font = new Font("Consolas", 8);
myChart.ChartAreas.Add(chartArea1);
myChart.Series.Add(new Series());
myChart.Series[0].XValueMember = myOutputDGV.Columns[1].DataPropertyName;
myChart.Series[0].YValueMembers = myOutputDGV.Columns[3].DataPropertyName;
myChart.DataSource = myOutputDGV.DataSource;
myChart.Series[0].ChartType = SeriesChartType.Line;
EDIT 2: 编辑2:
I have also tried this to no avail: 我也尝试这样做无济于事:
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChartArea.AxisX.MajorGrid.LineColor = Color.Red;
myChartArea.AxisY.MajorGrid.LineColor = Color.Red;
myChartArea.AxisX.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChartArea.AxisY.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
EDIT 3 FULL CODE: 编辑3个完整代码:
private void ProcessButton_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(myInputBox.Text) || myInputBox.Text == "")
{
MessageBox.Show("Please enter data", "Info");
}
else
{
myOutputDGV.Rows.Clear();
myOutputDGV.Columns.Clear();
myOutputDGV.Refresh();
myChart.ChartAreas.Clear();
myChart.Series.Clear();
List<string> mySplit = new List<string>(myInputBox.Text.Split(new string[] { "XN" }, StringSplitOptions.None));
DataGridViewTextBoxColumn myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Line";
myOutputGrid.Name = "Line";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Section";
myOutputGrid.Name = "Section";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost Range";
myOutputGrid.Name = "Cost Range";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost First Row";
myOutputGrid.Name = "Cost First Row";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost All Rows";
myOutputGrid.Name = "Cost All Rows";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Rows";
myOutputGrid.Name = "Rows";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Width";
myOutputGrid.Name = "Width";
myOutputDGV.Columns.Add(myOutputGrid);
foreach (string item in mySplit)
{
myOutputDGV.Rows.Add(item.Trim(),
item.Split(new string[] { "(cost=" }, StringSplitOptions.None).First(),
Regex.Match(item, @"cost=(.+?) rows").Groups[1].Value,
Regex.Match(item, @"cost=(.+?)\.\.").Groups[1].Value,
Regex.Match(item, @"\.\.(.+?) ").Groups[1].Value,
Regex.Match(item, @"rows=(.+?) ").Groups[1].Value,
Regex.Match(item, @"width=(.+?)\)").Groups[1].Value);
}
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChartArea.AxisX.MajorGrid.LineColor = Color.Red;
myChartArea.AxisY.MajorGrid.LineColor = Color.Red;
myChartArea.AxisX.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChartArea.AxisY.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
myChart.Series[0].XValueMember = myOutputDGV.Columns[1].DataPropertyName;
myChart.Series[0].YValueMembers = myOutputDGV.Columns[3].DataPropertyName;
myChart.DataSource = myOutputDGV.DataSource;
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
}
}
EDIT 4 i have grids and half a line: 编辑4我有网格和半行:
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
string dataxx = datax.ToString();
string datayy = datay.ToString();
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
myChart.Series[0].Points.AddXY(dataxx, datayy);
If you want to preserve your code as much as possible, you can fill a DataTable
instead of the DataGridView
and use that as the DataSource
in both the DataGridView
and Chart
. 如果要尽可能保留代码,则可以填充
DataTable
而不是DataGridView
并将其用作DataGridView
和Chart
的DataSource
。
Following code is roughly what you need to do for this case: Declare the DataTable
, create Columns
(of correct types, I just guessed them!), fill the Rows
, and use it as DataSource
. 在这种情况下,下面的代码大致是您需要做的:声明
DataTable
,创建Columns
(正确的类型,我只是猜到了!),填充Rows
,并将其用作DataSource
。
The benefits are clear: You will have forced data-types and you can use a breakpoint and VS Data Visualizer to check, if the content looks as expected (but you'll see it in this case in DataGridView
too). 好处很明显:您将拥有强制的数据类型,并且可以使用断点和VS Data Visualizer来检查内容是否符合预期(但在这种情况下,您也会在
DataGridView
看到它)。 It might be the data type giving you a trouble in the chart
. 可能是数据类型给
chart
带来了麻烦。
C# (translated): C#(翻译):
private DataTable dt;
private void MyForm_Load()
{
LoadDefaults();
}
private void LoadDefaults()
{
dt.Columns.Add("Line", typeof(Int16));
dt.Columns.Add("Section", typeof(string));
dt.Columns.Add("Range", typeof(string));
dt.Columns.Add("Total", typeof(float));
}
private void processButton_Click(object sender, EventArgs e)
{
foreach (var Item in mySplit) {
dt.Rows.Add({Item.Trim(), ......});
}
this.DataGridView1.DataSource = dt;
...
myChart.DataSource = dt;
}
VB.NET VB.NET
Dim dt As DataTable
Private Sub MyForm_Load()
Call LoadDefaults()
End Sub
Private Sub LoadDefaults()
dt.Columns.Add("Line", GetType(Int16))
dt.Columns.Add("Section", GetType(String))
dt.Columns.Add("Range", GetType(String))
dt.Columns.Add("Total", GetType(Single))
End Sub
Private Sub processButton_Click(sender As Object, e As EventArgs) Handles BtnExcel.Click
For Each Item In mySplit
dt.Rows.Add({Item.Trim(), Item.Split("(cost=", StringSplitOptions.None).First(), Regex.Match(Item, @"cost=(.+?) rows").Groups[1].Value, Regex.Match(Item, @"cost=(.+?)\.\.").Groups[1].Value})
Next
Me.DataGridView1.DataSource = dt
...
myChart.DataSource = dt
End Sub
EDIT - debugging charts example: 编辑 -调试图表示例:
There are many ways to use Chart DataBinding . 有很多使用Chart DataBinding的方法 。 - I suggest, when binding, not to bind to the chart but to the
Points
of a Series
! -我建议在绑定时不要绑定到图表,而是绑定到
Series
的Points
! - This way you can control things better, like choosing which Series
to bind to. -通过这种方式,您可以更好地控制事物,例如选择要绑定到的
Series
。
An example..: 一个例子..:
var datax = dataGridView1.Rows
.Cast<DataGridViewRow>().Select(x => x.Cells[ixName].Value).ToList();
var datay = dataGridView1.Rows
.Cast<DataGridViewRow>().Select(x => x.Cells[yName].Value).ToList();
aSeries.Points.DataBindXY(datax, datay);
..where xName
and yName
can be names or indices of the DGV Columns
. ..其中
xName
和yName
可以是DGV Columns
名称或索引。
But, as has been suggested, using a DataTable
is recommended. 但是,正如建议的那样,建议使用
DataTable
。 In any case you need an IEnumerable
to bind. 无论如何,您都需要一个
IEnumerable
进行绑定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.