[英].CSV to DataGridView Rows coming up blank in VB.NET
这是我要导入到VB.NET应用程序中的CSV数据:
但是,当我通过应用程序运行它时,它只会填充最后一行:
这是导入的代码:
Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
DataGridView1.ClearSelection()
ofd.Filter = "(*csv)|*.csv"
If ComboBox1.Text = "zVBImportTEST" Then
If (ofd.ShowDialog() = DialogResult.OK) Then
txtbxFilePath.Text = ofd.FileName
End If
Dim colsexpected As Integer = 6
Dim thereader As New StreamReader(txtbxFilePath.Text, Encoding.ASCII)
Dim sline As String = ""
thereader.ReadLine()
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(",")
DataGridView1.Rows.Add("")
For ix As Integer = 0 To 5
DataGridView1.Rows(DataGridView1.Rows.Count - 1).Cells(ix).Value = words(ix)
Next
Loop
thereader.Close()
Else
MessageBox.Show("Please select a project.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
End If
End Sub
我似乎无法弄清楚为什么其他行变成空白。 如果有人可以帮助我,将不胜感激。
我不建议尝试通过StreamReader读取数据,而是在传递CSV文件的连接字符串时使用OleDb类。
这是一个基于CSV文件内容返回DataTable的函数的快速示例:
Private Function ConvertCSVToDataTable(ByVal path As String) As DataTable
Dim dt As DataTable = New DataTable()
Using con As OleDb.OleDbConnection = New OleDb.OleDbConnection()
Try
con.ConnectionString = String.Format("Provider={0};Data Source={1};Extended Properties=""Text;HDR=YES;FMT=Delimited""", "Microsoft.Jet.OLEDB.4.0", IO.Path.GetDirectoryName(path))
Using cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand("SELECT * FROM " & IO.Path.GetFileName(path), con)
Using da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(cmd)
con.Open()
da.Fill(dt)
con.Close()
End Using
End Using
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
If con IsNot Nothing AndAlso con.State = ConnectionState.Open Then
con.Close()
End If
End Try
End Using
Return dt
End Function
接下来是绑定DataGridView的方法:
DataGridView1.DataSource = Me.ConvertCSVToDataTable(ofd.FileName)
更新
由于您要指定DataColumn的数据类型,因此可以声明一个DataTable并将其分配给自定义函数,但是要事后修改特定列的数据类型。 这是一个快速的示例(自由类型且未经测试):
Dim csv As DataTable = Me.ConvertCSVToDataTable(ofd.FileName)
With csv.Columns
.Items(0).DataType = GetType(Int32)
.Items(1).DataType = GetType(Int32)
.Items(4).DataType = GetType(Int32)
.Items(5).DataType = GetType(Int32)
End With
DataGridView1.DataSource = csv
这是C#,但是代码段显示了您当前正在做什么,以及如何进行操作以使其正常工作。
using System.Collections.Generic;
using System.Windows.Forms;
namespace DataGridNoBinding_47308996
{
public partial class Form1 : Form
{
DataGridView dgv = new DataGridView();
public Form1()
{
InitializeComponent();
dgv.Dock = DockStyle.Fill;
dgv.AutoGenerateColumns = false;
dgv.Columns.Add("Key","Key");
dgv.Columns.Add("Value", "Value");
this.Controls.Add(dgv);
Dictionary<string, string> dgvdata = new Dictionary<string, string>();
for (int i = 0; i < 10; i++)
{
dgvdata.Add($"key{i}", $"value{i}");
}
//AddToGridNoWork(dgvdata);
AddToGridDoesWork(dgvdata);
}
/// <summary>
/// This method does not work. This emulates what you are currently doing.
/// </summary>
/// <param name="dgvdata"></param>
private void AddToGridNoWork(Dictionary<string, string> dgvdata)
{
foreach (KeyValuePair<string, string> item in dgvdata)
{
dgv.Rows.Add();
dgv.Rows[dgv.Rows.Count - 1].Cells[0].Value = item.Key;
dgv.Rows[dgv.Rows.Count - 1].Cells[1].Value = item.Value;
dgv.Refresh();
}
}
/// <summary>
/// This method does work.
/// Add a new row to the Grid and store the new row index in rowindex
/// Then use the variable rowindex to update the correct row
/// </summary>
/// <param name="dgvdata"></param>
private void AddToGridDoesWork(Dictionary<string, string> dgvdata)
{
foreach (KeyValuePair<string, string> item in dgvdata)
{
int rowindex = dgv.Rows.Add();
dgv.Rows[rowindex].Cells[0].Value = item.Key;
dgv.Rows[rowindex].Cells[1].Value = item.Value;
}
}
}
}
在您的VB.net应用程序中,可能只是做这样的事情
dim newRowIndex as Integer
newRowIndex = DataGridView1.Rows.Add("")
For ix As Integer = 0 To 5
DataGridView1.Rows(newRowIndex).Cells(ix).Value = words(ix)
Next
改用DataDriver,这是我的代码,使用数据驱动程序代替StreamReader旋转
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data;
namespace DataGridNoBinding_47308996
{
public partial class Form1 : Form
{
DataGridView dgv = new DataGridView();
public Form1()
{
InitializeComponent();
dgv.Dock = DockStyle.Fill;
this.Controls.Add(dgv);
Dictionary<string, string> dgvdata = new Dictionary<string, string>();
for (int i = 0; i < 10; i++)
{
dgvdata.Add($"key{i}", $"value{i}");
}
//AddToGridNoWork(dgvdata);
//AddToGridDoesWork(dgvdata);
//AddToGridUsingDataDriver(@"M:\StackOverflowQuestionsAndAnswers\DataGridNoBinding_47308996\SampleData.csv");
AddToGridByBindingTheWholeTable(@"M:\StackOverflowQuestionsAndAnswers\DataGridNoBinding_47308996\SampleData.csv");
}
/// <summary>
/// This method will do what you want using a Data Driver instead of a StreamReader
/// Though, this method binds the whole DataTable to the DataGridView instead of manually creating 1 row per data row
/// </summary>
/// <param name="dataFilePath"></param>
private void AddToGridByBindingTheWholeTable(string dataFilePath)
{
dgv.AutoGenerateColumns = true;
string connstring = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={System.IO.Path.GetDirectoryName(dataFilePath)};Extended Properties=\"Text;HDR=NO;FMT=Delimited\"";
OleDbConnection conn = new OleDbConnection(connstring);
OleDbCommand command = new OleDbCommand($"select * from {System.IO.Path.GetFileName(dataFilePath)}", conn);
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
conn.Open();
dataAdapter.Fill(dt);
conn.Close();
dgv.DataSource = dt;
}
/// <summary>
/// This method will do what you want using a Data Driver instead of a StreamReader
/// In this method, we are actively creating 1 DataGridRow for each DataRow in the DataTable
/// </summary>
/// <param name="dataFilePath"></param>
private void AddToGridUsingDataDriver(string dataFilePath)
{
dgv.AutoGenerateColumns = false;
dgv.Columns.Add("Key", "Key");
dgv.Columns.Add("Value", "Value");
string connstring = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={System.IO.Path.GetDirectoryName(dataFilePath)};Extended Properties=\"Text;HDR=NO;FMT=Delimited\"";
OleDbConnection conn = new OleDbConnection(connstring);
OleDbCommand command = new OleDbCommand($"select * from {System.IO.Path.GetFileName(dataFilePath)}", conn);
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
conn.Open();
dataAdapter.Fill(dt);
conn.Close();
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow item in dt.Rows)
{
int newrowid = dgv.Rows.Add();
dgv.Rows[newrowid].Cells[0].Value = item.Field<string>(0);
dgv.Rows[newrowid].Cells[1].Value = item.Field<string>(1);
}
}
dgv.Refresh();
}
/// <summary>
/// This method does not work. This emulates what you are currently doing.
/// </summary>
/// <param name="dgvdata"></param>
private void AddToGridNoWork(Dictionary<string, string> dgvdata)
{
dgv.AutoGenerateColumns = false;
dgv.Columns.Add("Key","Key");
dgv.Columns.Add("Value", "Value");
foreach (KeyValuePair<string, string> item in dgvdata)
{
dgv.Rows.Add();
dgv.Rows[dgv.Rows.Count - 1].Cells[0].Value = item.Key;
dgv.Rows[dgv.Rows.Count - 1].Cells[1].Value = item.Value;
dgv.Refresh();
}
}
/// <summary>
/// This method does work.
/// Add a new row to the Grid and store the new row index in rowindex
/// Then use the variable rowindex to update the correct row
/// </summary>
/// <param name="dgvdata"></param>
private void AddToGridDoesWork(Dictionary<string, string> dgvdata)
{
dgv.AutoGenerateColumns = false;
dgv.Columns.Add("Key", "Key");
dgv.Columns.Add("Value", "Value");
foreach (KeyValuePair<string, string> item in dgvdata)
{
int rowindex = dgv.Rows.Add();
dgv.Rows[rowindex].Cells[0].Value = item.Key;
dgv.Rows[rowindex].Cells[1].Value = item.Value;
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.