How to handle result in SaveFileDialog - c#

public void SaveAs()
{
if(dataGridView1.ColumnCount>=2)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Excel files (*.xls)|*.xls";
saveFileDialog.FilterIndex = 0;
saveFileDialog.RestoreDirectory = true;
saveFileDialog.CreatePrompt = true;
saveFileDialog.Title = "Export Excel File To";
saveFileDialog.ShowDialog();
Stream myStream;
myStream = saveFileDialog.OpenFile();
StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));
string str = "";
try
{
for (int i = 0; i < dataGridView1.ColumnCount; i++)
{
if (i > 0)
{
str += "\t";
}
str += dataGridView1.Columns[i].HeaderText;
}
sw.WriteLine(str);
for (int j = 0; j < dataGridView1.Rows.Count; j++)
{
string tempStr = "";
for (int k = 0; k < dataGridView1.Columns.Count; k++)
{
if (k > 0)
{
tempStr += "\t";
}
tempStr += dataGridView1.Rows[j].Cells[k].Value.ToString();
}
sw.WriteLine(tempStr);
}
sw.Close();
myStream.Close();
}
catch (Exception e)
{
// MessageBox.Show(e.ToString());
}
finally
{
sw.Close();
myStream.Close();
}
}
else
MessageBox.Show("No data to save", "OK",
MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
}
When I open the saving window and I decide not to save DataGridView1 by clicking Cancel I have an error Index was outside the bounds of the array. at
myStream = saveFileDialog.OpenFile();
I don't know what's wrong in here.

Your culprit code is here:
saveFileDialog.ShowDialog();
Stream myStream;
myStream = saveFileDialog.OpenFile();
It should be like such:
if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
// code here for user pressing OK instead of the 'X' or 'Cancel'
Stream myStream = saveFileDialog.OpenFile();
}
Without that check if you close the dialog (via the 'x') or press Cancel, your saveFileDialog has some "empty" values that you try and reference (which gives you the error).

The function ShowDialog() returns a DialogResult to determine what action was taken. Just check the return value there before you continue. For example:
if(saveFileDialog.ShowDialog() == DialogResult.Cancel)
{
//do something else here or just return
return;
}

Related

Save datagrid information to text file shows an empty file

I have code that allows you to save datagrid information in visual studio into a text file but the datagrid is filled out and it just shows nothing in the text file
Code:
private void button3_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = "untitled.txt";
sfd.DefaultExt = "txt";
sfd.Filter = "txt files (*.text) |*.txt*";
if (sfd.ShowDialog() == DialogResult.OK)
{
Stream fileStream = sfd.OpenFile();
StreamWriter sw = new StreamWriter(fileStream);
for(int i = 0; i < dataGridView1.Rows.Count - 1; i++) //rows
{
for (int j = 0; j < dataGridView1.Columns.Count; j++) // columns
{
sw.Write("\t", dataGridView1.Rows[i].Cells[j].Value.ToString() + "\t" + "|");
}
sw.WriteLine("");
}
sw.Close();
fileStream.Close();
}
}
In my small tests, it appears the “\t” is getting misinterpreted. Fortunately, a simple fix is to simply make a Tab string and use it like…
string tab = "\t";
Then…
sw.Write( tab + dataGridView1.Rows[i].Cells[j].Value.ToString() + tab + "|");
In addition, it is a good idea to implement using statements to ensure the resources get closed and disposed of properly. Something like…
private void button2_Click(object sender, EventArgs e) {
using (SaveFileDialog sfd = new SaveFileDialog()) {
sfd.FileName = "untitled.txt";
sfd.DefaultExt = "txt";
sfd.Filter = "txt files (*.text) |*.txt*";
string tab = "\t";
if (sfd.ShowDialog() == DialogResult.OK) {
using (Stream fileStream = sfd.OpenFile()) {
using (StreamWriter sw = new StreamWriter(fileStream)) {
for (int i = 0; i < dataGridView1.Rows.Count; i++) {
if (!dataGridView1.Rows[i].IsNewRow) {
for (int j = 0; j < dataGridView1.Columns.Count; j++) {
sw.Write(tab + dataGridView1.Rows[i].Cells[j].Value.ToString());
if (j < dataGridView1.Columns.Count - 1) {
sw.Write(tab + "|");
}
}
sw.WriteLine("");
}
}
//sw.Close();
//fileStream.Close();
}
}
}
}
}
Here is an option
using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace YourNamespaceGoesHere
{
public static class DataGridViewExtensions
{
public static void ExportRows(this DataGridView sender, string fileName, string defaultNullValue = "(empty)")
{
File.WriteAllLines(fileName, (sender.Rows.Cast<DataGridViewRow>()
.Where(row => !row.IsNewRow)
.Select(row => new {
row,
rowItem = string.Join(",", Array.ConvertAll(row.Cells.Cast<DataGridViewCell>()
.ToArray(), c => ((c.Value == null) ? defaultNullValue : c.Value.ToString())))
})
.Select(#row => #row.rowItem)));
}
}
}
Usage (replace the file name from your SaveFileDialog)
private void ExportButton_Click(object sender, EventArgs e)
{
dataGridView1.ExportRows("data1.txt");
}

C# Excel to .TXT

I'm starting to play with C# / .NET. My work background is Python.
Im having difficulty solving the conversion from Excel to TXT.
What i need the txt file to look like is:
ROW1COLUM1;ROW1COLUM2;ROW1COLUM3 //Note the lack of ";" on line break.
ROW2COLUM1;ROW2COLUM2;ROW3COLUM3
I am trying to at least save 1 cell in the txt but i cant. Code below:
private void button1_Click(object sender, EventArgs e) // Go
{
File.Create(#"C: \Users\AG\.PyCharmCE2017.2\config\scratches\testnet.txt").Close();
TextWriter tw = new StreamWriter(#"C: \Users\AG\.PyCharmCE2017.2\config\scratches\testnet.txt");
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(fileName);
Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Excel.Range xlRange = xlWorksheet.UsedRange;
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
string[] dataRow = new string[15]; //fixed number for now
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
dataRow[j - 1] = xlWorksheet.Cells[i, j].Value.ToString();
}
tw.WriteLine(dataRow[1]); // Just checking if i can write something
}
MessageBox.Show("OK");
tw.Close();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
I also need to save the .txt file as unicode, in case that matters.
This is probably very basic, i just couldn't find an answer.
Thanks
EDIT:
I managed to make it work. I also added a backgroundWorker.
The problem i have is performance. Can someone point me in the right direction?
Code:
if (goNoGo)
{
string sourceDirectory = Path.GetDirectoryName(fileName);
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
File.Create(sourceDirectory + filenameWithoutExtension).Close();
TextWriter tw = new StreamWriter(sourceDirectory + "\\" + filenameWithoutExtension + ".txt", true, Encoding.Unicode);
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(fileName);
Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Excel.Range xlRange = xlWorksheet.UsedRange;
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
string dataRow = "";
int z = 1;
if (checkBox1.Checked)
{
z = 2;
}
int cont = 0;
for (float i = z; i <= rowCount; i++)
{
if (i % 250 == 0) // every 250 rows, check BW updates
{
cont = ((int)((i / rowCount) * 100));
backgroundWorker1.ReportProgress(cont);
//MessageBox.Show(cont.ToString());
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
for (int j = 1; j <= colCount; j++)
{
try
{
if (j == 1)
{
dataRow = xlWorksheet.Cells[i, j].Value.ToString();
}
else
{
dataRow += ";";
dataRow += xlWorksheet.Cells[i, j].Value.ToString();
}
}
catch (Exception ex) // catches empty cells
{
if (j == 1)
{
dataRpw = "";
}
else
{
dataRow += ";";
dataRow += "";
}
continue;
}
}
tw.WriteLine(dataRow);
}
tw.Close();
//cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
backgroundWorker1.ReportProgress(100);
}
else if (extensionWrong)
{
MessageBox.Show("File must be .xls");
}
else
{
MessageBox.Show("Load a file");
}
A 30k row file can take up to an hour. Any ideas?
Please try this and feedback.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Excel;
namespace test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataSet result = new DataSet();
private void button1_Click(object sender, EventArgs e)
{
string fileName = "";
fileName = textBox3.Text;
if (fileName == "")
{
MessageBox.Show("Enter Valid file name");
return;
}
converToCSV(comboBox1.SelectedIndex);
}
private void button2_Click(object sender, EventArgs e)
{
string Chosen_File = "";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
Chosen_File = openFileDialog1.FileName;
}
if (Chosen_File == String.Empty)
{
return;
}
textBox1.Text = Chosen_File;
getExcelData(textBox1.Text);
}
private void button3_Click(object sender, EventArgs e)
{
DialogResult result = this.folderBrowserDialog1.ShowDialog();
string foldername = "";
if (result == DialogResult.OK)
{
foldername = this.folderBrowserDialog1.SelectedPath;
}
textBox2.Text = foldername;
}
private void getExcelData(string file)
{
if (file.EndsWith(".xlsx"))
{
// Reading from a binary Excel file (format; *.xlsx)
FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
result = excelReader.AsDataSet();
excelReader.Close();
}
if (file.EndsWith(".xls"))
{
// Reading from a binary Excel file ('97-2003 format; *.xls)
FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
result = excelReader.AsDataSet();
excelReader.Close();
}
List<string> items = new List<string>();
for (int i = 0; i < result.Tables.Count; i++)
items.Add(result.Tables[i].TableName.ToString());
comboBox1.DataSource = items;
}
private void converToCSV(int ind)
{
// sheets in excel file becomes tables in dataset
//result.Tables[0].TableName.ToString(); // to get sheet name (table name)
string a = "";
int row_no = 0;
while (row_no < result.Tables[ind].Rows.Count)
{
for (int i = 0; i < result.Tables[ind].Columns.Count; i++)
{
a += result.Tables[ind].Rows[row_no][i].ToString() + ",";
}
row_no++;
a += "\n";
}
string output = textBox2.Text + "\\" + textBox3.Text + ".csv";
StreamWriter csv = new StreamWriter(#output, false);
csv.Write(a);
csv.Close();
MessageBox.Show("File converted succussfully");
textBox1.Text = "";
textBox2.Text = "";
textBox3.Text = "";
comboBox1.DataSource = null;
return;
}
}
}

ContextMenu Click Event firing more than once

This is really strange, for some reason my contextmenu clicks are firing more than once. I have the contextmenu tied to a button, so when the button is clicked the contextmenu is shown under it (with more options).
One option is to save listview to Excel, the other is to save to .csv.
So basically what happens here is that multiple excel sheets will open. Of course I only want one excel to open :)
Here is my code:
private void toolButtonNoBorder3_Click(object sender, EventArgs e)
{
contexMenuuu.Show(toolButtonNoBorder3,
new Point(0, toolButtonNoBorder3.Height));
contexMenuuu.ItemClicked +=
new ToolStripItemClickedEventHandler(contexMenuuu_ItemClickedd);
}
void contexMenuuu_ItemClickedd(object sender, ToolStripItemClickedEventArgs e)
{
contexMenuuu.Hide();
contexMenuuu.Close();
if (e.ClickedItem.Text == "Excel")
{
Microsoft.Office.Interop.Excel.Application app =
new Microsoft.Office.Interop.Excel.Application();
app.Visible = true;
Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Add(1);
Microsoft.Office.Interop.Excel.Worksheet ws =
(Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1];
int i = 1;
int i2 = 1;
int iad = 1;
foreach (ListViewItem lvi in flatListView1.Items)
{
i = 1;
foreach (ListViewItem.ListViewSubItem lvs in lvi.SubItems)
{
if (i2 == 1)
{
iad = 1;
foreach (ColumnHeader lvfi in flatListView1.Columns)
{
try
{
ws.Cells[i2, iad] = lvfi.Text;
}
catch (Exception ee)
{
}
iad++;
}
}
else
{
try
{
ws.Cells[i2, i] = lvs.Text;
}
catch (Exception ee)
{
}
}
i++;
}
i2++;
}
}
else if (e.ClickedItem.Text == "CSV")
{
Stream myStream;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "csv files (*.csv)|*.csv";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
myStream.Close();
ListViewToCSV(flatListView1, saveFileDialog1.FileName, true);
}
}
}
}
It should be in a constructor of your window:
public MyWindow()
{
//here inicialization
contexMenuuu.ItemClicked +=
new ToolStripItemClickedEventHandler(contexMenuuu_ItemClickedd);
}
This is a very common error to add event handler more than once, be careful next time
In my case I have solved it using following statement -
e.Handled = true;
This will mark the event as handled (Obviously).

import/export text to/from listview [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
i am having two problems:
1- when ever i click on open button, it shows me the openfiledialog twice (when i select my file and click ok, it reopens the selection windows again, only repeats it once).
2- i am trying to export and import text files from a list view, so far i managed to export a text file from the list view, but i failed at importing it back in.
here is my code (for both situations since it's the same project):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string path;
//string fname;
private void abtmenuItem10_Click(object sender, EventArgs e)
{
MessageBox.Show("DB Kai UB Text Extractor\n by Omarrrio 2012", "About...", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0, "http://gbatemp.net/user/245642-omarrrio/");
}
private void exitmenuItem4_Click(object sender, EventArgs e)
{
this.Close();
}
private void sbtmenuItem5_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open Sbt File";
ofd.Filter = "Sbt Files (*.sbt)|*.sbt|All Files (*.*)|*.*";
//if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
}
private void msgmenuItem6_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
pntrsmenuItem4.Text = "Number of Pointer = ";
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open Msg File";
ofd.InitialDirectory = Application.StartupPath;
ofd.Filter = "Msg Files (*.msg)|*.msg|All Files (*.*)|*.*";
DialogResult result = ofd.ShowDialog();
if (result == DialogResult.Cancel)
return;
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
path = ofd.FileName;
BinaryReader br = new BinaryReader(File.OpenRead(path), Encoding.GetEncoding("Shift_JIS"));
br.BaseStream.Position = 0x4;
int num_pointers = br.ReadInt16();
if (num_pointers == 0x56C)
{
MessageBox.Show("This File is not supported as it's pointer system is somehow F*cked up, please use another file, thank you.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
}
else
{
MessageBox.Show("File opened Succesfully!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
pntrsmenuItem4.Visible = true;
pntrsmenuItem4.Text += num_pointers.ToString();
List<int> offsets = new List<int>();
for (int i = 2; i <= (num_pointers * 2); i += 2)
{
br.BaseStream.Position = i * 4 + 4;
offsets.Add(br.ReadInt32());
//listView1.Items.Add(br.ReadUInt32().ToString("X"));
}
Dictionary<int, string> values = new Dictionary<int, string>();
for (int i = 0; i < offsets.Count; i++)
{
int currentOffset = offsets[i];
int nextOffset = (i + 1) < offsets.Count ? offsets[i + 1] : (int)br.BaseStream.Length;
int stringLength = (nextOffset - currentOffset - 1) / 2;
br.BaseStream.Position = currentOffset;
var chars = br.ReadChars(stringLength);
values.Add(currentOffset, new String(chars));
}
foreach (int offset in offsets)
{
listView1.Items.Add(offset.ToString("X")).SubItems.Add(values[offset]);
}
br.Close();
br = null;
}
}
ofd.Dispose();
ofd = null;
}
private void EtxtmenuItem8_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "Save Text File";
sfd.DefaultExt = ".txt";
sfd.InitialDirectory = Application.StartupPath;
sfd.Filter = "Text Files (*.txt)|*.txt";
DialogResult result = sfd.ShowDialog();
if (result == DialogResult.Cancel)
return;
StreamWriter wwrite = new StreamWriter(sfd.FileName, false, Encoding.Unicode);
for (int i = 0; i < listView1.Items.Count; ++i)
{
string name = listView1.Items[i].SubItems[1].Text;
wwrite.WriteLine("-" + name);
}
wwrite.Close();
}
private void ItxtmenuItem4_Click(object sender, EventArgs e)
{
OpenFileDialog ifd = new OpenFileDialog();
ifd.Title = "Open Text File";
ifd.Filter = "Text Files (*.txt)|*.txt";
ifd.InitialDirectory = Application.StartupPath;
DialogResult result = ifd.ShowDialog();
if (result == DialogResult.Cancel)
return;
StreamReader sr = new StreamReader(ifd.FileName);
int aa = 0;
while (sr.Peek() >= 0)
{
string[] a2 = sr.ReadLine().Split('-');
if (a2.Length == 2)
{
aa = int.Parse(a2[0].ToString());
listView1.Items[aa].SubItems[1].Text = a2[1].Replace("~", "\n");
}
else
{
listView1.Items[aa].SubItems[1].Text += "\n" + a2[0];
}
}
sr.Close();
}
}
It's a bit hard to see which Menu click corresponds to which method here, but I'll I'm guessing that the offending piece of code is msgmenuItem6_Click.
The reason that the Dialog is showing up twice is because you call ShowDialog twice.
DialogResult result = ofd.ShowDialog();
if (result == DialogResult.Cancel)
return;
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
You should be doing
if (result == System.Windows.Forms.DialogResult.OK)
Regarding why you aren't able to read your file. Are you certain that there is data in the while you're trying to read? To ensure that you are opening it correctly, you can also try File.ReadAllText and make sure that it's being read in correctly.

how to save data loaded from external file into the program?

Based on the function below, it is used to load data from file .dat. The problem is every time i load a new file, the previous file will be overwritten. how to store the data from previous file inside the program so that when loading a new file, the new data will be added to the previous one?
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Data File (*.dat)|*.dat";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
TextReader f = new StreamReader(openFileDialog1.FileName);
String line;
this.letterData.Clear();
this.letters.Items.Clear();
while ((line = f.ReadLine()) != null)
{
int sampleSize = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
char ch = char.ToUpper(line[0]);
bool[] sample = new bool[sampleSize];
int idx = 2;
for (int i = 0; i < sampleSize; i++)
{
if (line[idx++] == '1')
sample[i] = true;
else
sample[i] = false;
}
this.letterData.Add(ch, sample);
this.letters.Items.Add("" + ch);
}
f.Close();
}
MessageBox.Show(this, "File Loaded");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
Remove the following lines?
this.letterData.Clear();
this.letters.Items.Clear();
EDIT:
Or change to te following in order to have unique keys in your dictionary
this.letterData.Add(string.Format("{0}_{1}", openFileDialog1.FileName, ch), sample);
this.letters.Items.Add(ch.toString());

Categories