This is my button to save file:
private void metroButton12_Click(object sender, EventArgs e) // save
{
DataSet ds = (DataSet)dataGridView1.DataSource;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "XML|*.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
try
{
ds.Tables[0].WriteXml(sfd.FileName);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
I try to safe my datagridview to XML but nothing happpend when I choose file.
When I start console I see this:
System.NullReferenceException: The object reference was not set to an object instance.
My gridview look like:
ID Name
1 Michale
2 Noob
What am I doing here wrong?.. I saw a lot of thing's on the web but could not find any solutions in stackoverflow and other forums.
Please be patient for newbie guys. Thank you!
To me it sounds like your problem is not where you think it is.
when i start console i see this : System.NullReferenceException: The object reference was not set to an object instance.
To me you are implying that you get the message when you launch the application, not when you click the button. If you get the error before you click, your problem is elsewhere and not in the code snippet you posted. Here is a complete and testable snippet of what you are currently doing.
using System;
using System.Data;
using System.Windows.Forms;
namespace DataGridViewToXML_43053387
{
public partial class Form1 : Form
{
//DataSet theDataSet;
public Form1()
{
InitializeComponent();
InsertDgvIntoForm();
ExportDgvToXML();
}
private void InsertDgvIntoForm()
{
//create a data set
DataSet ds = new DataSet();
//create a data table for the data set
DataTable dt = new DataTable();
//create some columns for the datatable
DataColumn dc = new DataColumn("ItemName");
DataColumn dc2 = new DataColumn("ItemValue");
DataColumn dc3 = new DataColumn("Blah");
DataColumn dc4 = new DataColumn("Bleh");
//add the columns to the datatable
dt.Columns.Add(dc);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Columns.Add(dc4);
//create 5 rows of irrelevant information
for (int i = 0; i < 5; i++)
{
DataRow dr = dt.NewRow();
dr["ItemName"] = "Item" + i + "Name";
dr["ItemValue"] = "Item" + i + "Value";
dr["Blah"] = "Item" + i + "Blah";
dr["Bleh"] = "Item" + i + "Bleh";
dt.Rows.Add(dr);
}
//add the datatable to the datasource
ds.Tables.Add(dt);
//just because it looks better on my screen
dataGridView1.AutoSize = true;
//make this data the datasource of our gridview
dataGridView1.DataSource = ds.Tables[0];
}
private void ExportDgvToXML()
{
DataTable dt = (DataTable)dataGridView1.DataSource;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "XML|*.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
try
{
dt.WriteXml(sfd.FileName);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
}
blaze_125 answer didn't help me so I've found this solution:
private void btnXML_Save_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.TableName = "Bank";
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
//if (dataGridView1.Columns[i].Visible) // Add's only Visible columns (if you need it)
//{
string headerText = dataGridView1.Columns[i].HeaderText;
headerText = Regex.Replace(headerText, "[-/, ]", "_");
DataColumn column = new DataColumn(headerText);
dt.Columns.Add(column);
//}
}
foreach (DataGridViewRow DataGVRow in dataGridView1.Rows)
{
DataRow dataRow = dt.NewRow();
// Add's only the columns that you want
dataRow["BLZ"] = DataGVRow.Cells["BLZ"].Value;
dataRow["Test_1"] = DataGVRow.Cells["Test 1"].Value;
dataRow["Test_2"] = DataGVRow.Cells["Test-2"].Value;
dataRow["PIN_TAN_Test_URL"] = DataGVRow.Cells["PIN/TAN-Test URL"].Value;
dt.Rows.Add(dataRow); //dt.Columns.Add();
}
DataSet ds = new DataSet();
ds.Tables.Add(dt);
//Finally the save part:
XmlTextWriter xmlSave = new XmlTextWriter(XML_Save_Path_Filename, Encoding.UTF8);
xmlSave.Formatting = Formatting.Indented;
ds.DataSetName = "Data";
ds.WriteXml(xmlSave);
xmlSave.Close();
}
Result will look like this:
<Data>
<Bank>
<BLZ>10000001</BLZ>
<Test_1>server.bank.com</Test_1>
<Test_2>V3.0</Test_2>
<PIN_TAN_Test_URL>https://test.bank.com/</PIN_TAN_Test_URL>
</Bank>
....
<Bank>
<BLZ>12396123</BLZ>
<HBCI_Zugang_DNS>test01.test.com</HBCI_Zugang_DNS>
<HBCI_Version>V3.0</HBCI_Version>
<PIN_TAN_Test_URL>https://test11.test.com</PIN_TAN_Test_URL>
</Bank>
</Data>
Related
This is the button which I press in order the csv-s to be imported:
private void btnOpen_Click_1(object sender, EventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
// string[] files = Directory.GetFiles(fbd.SelectedPath);
string[] csvFiles = Directory.GetFiles(#"D:\CSV", "*.csv");
foreach (string filePath1 in csvFiles)
{
BindData(filePath1);
}
}
}
}
This is the method that is called for each csv. The problem is that it makes the datagridview each time the last csv is imported. I want a way that adds all the records not only my last imported csv:
private void BindData(string filePath)
{
DataTable dt = new DataTable();
using (TextFieldParser parser = new TextFieldParser(filePath))
{
// configure your parser to your needs
parser.TextFieldType = FieldType.Delimited;
parser.Delimiters = new string[] { ";" };
parser.HasFieldsEnclosedInQuotes = false; // no messy code if your data comes with quotes: ...;"text value";"another";...
// read the first line with your headers
string[] fields = parser.ReadFields();
// add the desired headers with the desired data type
dt.Columns.Add(fields[0], typeof(string));
dt.Columns.Add(fields[1], typeof(string));
dt.Columns.Add(fields[6], typeof(float));
dt.Columns.Add(fields[7], typeof(float));
dt.Columns.Add(fields[8], typeof(string));
dt.Columns.Add(fields[9], typeof(string));
// read the rest of the lines from your file
while (!parser.EndOfData)
{
// all fields from one line
string[] line = parser.ReadFields();
// create a new row
DataRow row = dt.NewRow();
// put data values; cast if needed - this example uses string type columns
row[0] = line[0];
row[1] = line[1];
row[2] = line[6];
row[3] = line[7];
row[4] = line[8];
row[5] = line[9];
// add the newly created and filled row
dt.Rows.Add(row);
}
}
this.dataGridView1.DataSource = dt;
// asign to DGV
}
Change this line
DataTable dt = new DataTable();
So it says:
DataTable dt = (this.dataGridView1.DataSource as DataTable) ?? new DataTable();
So that you either reuse your existing data source or make a new one if it is not set
Im having difficulties loading from a text file and having that info placed into a data grid view that is data bound using a binding source.
private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text File|*.txt";
var result = openFileDialog.ShowDialog();
DataTable dataTable = (DataTable)MoviesDataGridView.DataSource;
DataRow dtRow = (DataRow)MoviesDataGridView.DataSource;
if (result != DialogResult.OK)
return;
try
{
using (myStream = openFileDialog.OpenFile())
{
string newline;
StreamReader file = new StreamReader(myStream);
while ((newline = file.ReadLine()) != null)
{
string[] lines = newline.Split('\t');
for (int i = 0; i < lines.Length; i++)
{
dtRow[i] = lines[i];
}
dataTable.Rows.Add(dtRow);
}
file.Close();
MoviesDataGridView.DataSource = dataTable;
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
Want it to open and then load into the dataGridView however i get this exception error:
System.InvalidCastException: 'Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.'
Replace:
DataTable dataTable = (DataTable)MoviesDataGridView.DataSource;
DataRow dtRow = (DataRow)MoviesDataGridView.DataSource;
With
DataTable dataTable = new DataTable();
Add columns to the table like this:
DataColumn column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
table.Columns.Add(column);
And create the new row in the while loop with:
DataRow dtRow = dataTable.NewRow();
You can try adding the code below
BindingSource SBind = new BindingSource();
SBind.DataSource = dataTable;
MoviesDataGridView.Columns.Clear();
MoviesDataGridView.DataSource = SBind;
Referenced from:
how to bind datatable to datagridview in c#
I have a form with 4textboxes + datagridview with 11columns.
Have from here a method to save datagridview this work fine, but is it possible to improve it so i can save not only the datagridview values, but the textboxes too??(then load too.)
thank you
Or is there something others that can be used for this?
private DataTable GetDataTableFromDGV(DataGridView dataGridView1)
{
var dt = new DataTable();
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
}
}
object[] cellValues = new object[dataGridView1.Columns.Count];
foreach (DataGridViewRow row in dataGridView1.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}
return dt;
}
private void SaveXML(object sender, EventArgs e)
{
//Savefile dialog for save CSV file
SaveFileDialog savefile = new SaveFileDialog();
savefile.FileName = tbOrderNr.Text + " - " + tbCustommer.Text + ".xml";
savefile.Filter = "xml files (*.xml)|*.xml";
if (savefile.ShowDialog() == DialogResult.OK)
{
DataTable dT = GetDataTableFromDGV(dataGridView1);
DataSet dS = new DataSet();
dS.Tables.Add(dT);
dS.WriteXml(File.OpenWrite(savefile.FileName));
}
}
}
Finaly i use save textboxes and datagridview through dataset.WriteXml
//XML save throught dataset
private void XMLsave(object sender, EventArgs e)
{
dataGridView1.AllowUserToAddRows = false;
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.TableName = "OrderData";
dt.Columns.Add("OrderNr");
dt.Columns.Add("Custommer");
dt.Columns.Add("Material");
dt.Columns.Add("MaterialCode");
ds.Tables.Add(dt);
DataTable dt1 = new DataTable();
dt1.TableName = "Data";
dt1.Columns.Add("Lenght");
dt1.Columns.Add("Width");
dt1.Columns.Add("Qty");
ds.Tables.Add(dt1);
DataRow row = ds.Tables["OrderData"].NewRow();
row["OrderNr"] = tbOrderNr.Text;
row["Custommer"] = tbCustommer.Text;
row["Material"] = tbMaterial.Text;
row["MaterialCode"] = tbForm2MatCode.Text;
ds.Tables["Data"].Rows.Add(row);
foreach (DataGridViewRow r in dataGridView1.Rows)
{
DataRow row1 = ds.Tables["Data"].NewRow();
row1["Lenght"] = r.Cells[0].Value;
row1["Width"] = r.Cells[1].Value;
row1["Qty"] = r.Cells[2].Value;
ds.Tables["Data"].Rows.Add(row1);
}
ds.WriteXml("test.xml");
dataGridView1.AllowUserToAddRows = true;
}
and then load it with:
private void XmlLoad(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ds.ReadXml("test.xml");
tbOrderNr.Text = ds.Tables["OrderData"].Rows[0][0].ToString();
tbCustommer.Text = ds.Tables["OrderData"].Rows[0][1].ToString();
tbMaterial.Text = ds.Tables["OrderData"].Rows[0][2].ToString();
tbForm2MatCode.Text = ds.Tables["OrderData"].Rows[0][3].ToString();
foreach (DataRow item in ds.Tables["Data"].Rows)
{
dataGridView1.AllowUserToAddRows = false;
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = tem["Lenght"].ToString();
dataGridView1.Rows[n].Cells[1].Value = item["Width"].ToString();
dataGridView1.Rows[n].Cells[2].Value = item["Qty"].ToString();
dataGridView1.AllowUserToAddRows = true;
}
I am grabbing eventlogs then displaying them in a datagrid, however for large logs it takes forever to return, so I would like to limit the logs by last 24hours but I am not sure how to do that. I would like to limit the collection prior to iterating through each entry because that would still take as long done that way. Any help would be totally appreciated!!!
namespace SysTools
{
public partial class LogViewer : Form
{
DataTable eventLog = new DataTable();
DataSet dataset1 = new DataSet();
private EventLog unhandledLogs;
public LogViewer(EventLog logs)
{
unhandledLogs = logs;
InitializeComponent();
}
private void LogViewer_Load(object sender, EventArgs e)
{
String currentLog = unhandledLogs.Log;
DataTable dataTable1 = new DataTable();
DataColumn column;
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Level";
dataTable1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Category";
dataTable1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.DateTime");
column.ColumnName = "DateTime";
dataTable1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Message";
dataTable1.Columns.Add(column);
dataTable1.Rows.Clear();
DateTime systemtime = new DateTime();
Int32 count = unhandledLogs.Entries.Count;
for (int currLogIndex = 0; currLogIndex <= unhandledLogs.Entries.Count; currLogIndex++)
{
DataRow drnew = dataTable1.NewRow();
try
{
EventLogEntry currLogEntrys = unhandledLogs.Entries[currLogIndex];
EventLogEntry currLogEntry = currLogEntrys;
string entrytype = currLogEntrys.EntryType.ToString();
drnew["Level"] = entrytype;
drnew["Category"] = currLogEntry.Source;
drnew["DateTime"] = currLogEntry.TimeGenerated;
drnew["Message"] = currLogEntry.Message;
dataTable1.Rows.Add(drnew);
}
catch { }
}
dataGridView1.DataSource = dataTable1;
dataTable1.DefaultView.Sort = ("DateTime asc");
}
}
}
Have a look at the EventLogQuery and EventLogReader classes. In my example below, I'm reading the past 24 hours worth of logs from the Application Event Log, and putting them into a list. You can easily adapt to suit you own log and needs.
Note I'm doing something moderately hacky to get the date into the expected format (you should improve that), but see how I'm creating a query and then only processing the retrieved records.
public void GetEvents()
{
string FormattedDateTime = string.Format("{0}-{1}-{2}T{3}:{4}:{5}.000000000Z",
DateTime.Now.Year,
DateTime.Now.Month.ToString("D2"),
DateTime.Now.AddDays(-1).Day.ToString("D2"),
DateTime.Now.Hour.ToString("D2"),
DateTime.Now.Minute.ToString("D2"),
DateTime.Now.Second.ToString("D2"));
string LogSource = #"Application";
string Query = "*[System[TimeCreated[#SystemTime >= '" + FormattedDateTime + "']]]";
var QueryResult = new EventLogQuery(LogSource, PathType.LogName, Query);
var Reader = new System.Diagnostics.Eventing.Reader.EventLogReader(QueryResult);
List<EventRecord> Events = new List<EventRecord>();
bool Reading = true;
while (Reading)
{
EventRecord Rec = Reader.ReadEvent();
if (Rec == null)
Reading = false;
Events.Add(Rec);
// You could add to your own collection here instead of adding to a list
}
}
In windows desktop application form I am using this code for deleting data from datagridview and database ,I have taken one checkbox column in dataridview ,If I click on checkbox row is getting deleted at that moment from datagridview ,but not from the database therefore when i reload form i can see that row again ,where I am going wrong?
public partial class EditEngClgList : Form
{
private OleDbConnection acccon = null;
private OleDbDataAdapter da = null;
private DataTable dt = null;
private BindingSource bs = null;
private OleDbCommandBuilder cmdb = null;
public EditEngClgList()
{
InitializeComponent();
try
{
acccon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb");
acccon.Open();
}
catch (Exception err)
{
MessageBox.Show("Error:" + err);
}
string sql = "Select * From EngColeges order by EngClgID";
da = new OleDbDataAdapter(sql, acccon);
cmdb = new OleDbCommandBuilder(da);
dt = new DataTable();
da.Fill(dt);
bs = new BindingSource();
bs.DataSource = dt;
dataGridView1.DataSource = bs;
dataGridView1.Columns[1].Visible = false;
dataGridView1.Columns[2].HeaderText = "Engineering College Name";
dataGridView1.Columns[3].HeaderText = "Adress";
dataGridView1.Columns[4].HeaderText = "Entrance Type";
dataGridView1.Columns[2].Width = 400;
}
private void button4_Click(object sender, EventArgs e)
{
List<int> checkedclg = new List<int>();
DataRow dr;
List<int> checkedclgid = new List<int>();
for (int i = 0; i <= dataGridView1.RowCount - 1; i++)
{
if (Convert.ToBoolean(dataGridView1.Rows[i].Cells["Delete"].Value) == true)
{
checkedclg.Add(i);
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
}
}
foreach (int k in checkedclg)
{
dr = dt.Rows[k];
dt.Rows[k].Delete();
foreach (int j in checkedclgid)
{
OleDbCommand oleDbCommand = new OleDbCommand("DELETE FROM EngColeges WHERE EngClgID = #clgID", acccon);
oleDbCommand.Parameters.Add("#clgID", OleDbType.Integer).Value = j;
oleDbCommand.Prepare();
oleDbCommand.ExecuteNonQuery();
}
}
}
if (Convert.ToBoolean(dataGridView1.Rows[i].Cells["Delete"].Value) == true)
{
checkedclg.Add(i);
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
}
Looks like the wrong cell value is being passed to Convert.ToInt16? It's using the "Deleted" column instead of your ID column.
Also you can delete all the rows in one sql statement using the where in clause, for example:
DELETE FROM table WHERE id IN (1, 2, 3, 4)
Insted of storing value of Delete like this
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
storing The values of primary key column like this deletes data properly from database Also
checkedclgid.Add(Convert.ToInt32(dataGridView1.Rows[i].Cells["EngClgID"].Value));
You must change this line:
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
to the following:
checkedclgid.Add(Convert.ToInt32(dataGridView1.Rows[i].Cells["CellInTheInvisible‌​Column"].Value));
Because you're converted a boolean type to Int16 and then you're used it in your query for checking with ID in your related table.
OleDbCommand oleDbCommand = new OleDbCommand("DELETE FROM EngColeges WHERE EngClgID = #clgID", acccon);
So, you must store ID of rows that you want to delete them.
I think first of all you are deleting the row and then you are attempting to delete it from database. First of all you delete the row from database and then again call the select query for that table.
All you have right now is a command. You need your OleDbDataAdapter, and pass the command to it:
...
da = new OleDbDataAdapter(sql, acccon);
da.DeleteCommand = oleDbCommand;
More Info: http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.deletecommand.aspx
Just replace these two lines:
oleDbCommand.Prepare();
oleDbCommand.ExecuteNonQuery();
With:
da.DeleteCommand = oleDbCommand;
References:
http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.deletecommand.aspx