I am writing a program that involves some heavy conversion of an Excel file into a very specifically formatted flat file. There are over 50,000 rows that need converted, so needless to say, it will take a while to process.
With that said, using a BackgroundWorker would make the most sense.
Everything I have executes properly and works fine except for one issue: trying to call the BackgroundWorker.ReportProgress() method from an instantiated class to update a counter on the parent Form.
If I'm not making sense, maybe my code will make more sense:
The Processing GUI Form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace CityTaxImport
{
public partial class Processing : Form
{
string s_sourceFile;
bool b_fileSaved;
CityConvert convert = new CityConvert();
public Processing(string s_incomingPath)
{
BackgroundWorker bg_Taxes = new BackgroundWorker();
s_sourceFile = s_incomingPath;
//background worker
bg_Taxes.DoWork += new DoWorkEventHandler(bg_Taxes_DoWork);
bg_Taxes.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_Taxes_RunWorkerCompleted);
bg_Taxes.ProgressChanged += new ProgressChangedEventHandler(bg_Taxes_ProgressChanged);
bg_Taxes.WorkerSupportsCancellation = true;
bg_Taxes.WorkerReportsProgress = true;
InitializeComponent();
bg_Taxes.RunWorkerAsync();
}
#region METHODS
#region BACKGROUND WORKER
//do work/runworker Async stuff
private void bg_Taxes_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg_Taxes = sender as BackgroundWorker;
CityConvert convert = new CityConvert();
convert.ConvertFile(s_sourceFile);
}
//when the worker completes, let user know, end program
private void bg_Taxes_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pb_Progress.MarqueeAnimationSpeed = 0;
//lets the user know the file is done and prompts them on where to save it at
if (MessageBox.Show(this, "The file has been created.\nChoose where you would like to save it.",
"Conversion Finished", MessageBoxButtons.OK, MessageBoxIcon.Asterisk) == DialogResult.OK)
{
while (b_fileSaved != true)
{
SaveFile();
}
}
}
//used to update the progress count
public void bg_Taxes_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//RIGHT HERE IS WHAT SHOULD UPDATE THE COUNTER
lb_recordCount.Text = convert.i_RowCount.ToString();
}
#endregion
And now the class with all of the hard work:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace CityTaxImport
{
class CityConvert
{
#region VARIABLES AND OBJECTS AND ALL THE OTHER VARS AND CHARS
//the Excel squad
Excel._Application xl_app;
Excel._Workbook xl_wrkBk;
Excel._Worksheet xl_wrkSht;
//our friend object Type.Missing
private object o_miss = Type.Missing;
//dataset and table
private DataSet ds_taxes;
private DataTable dt_taxes;
private DataRow dr_taxes;
//strings and counts and stuff
private string s_sourceFile;
private int i_xlRowTotal;
private int i_xlRowCount;
private int i_dtRowCount;
private string s_output;
public int i_RowCount{get; set;}
#endregion
#region METHODS
//the initial convert file method called by the main window
public bool ConvertFile(string s_selectedFile)
{
s_sourceFile = s_selectedFile;
CreateDataSet();
OpenExcel();
PopulateDateSet();
WriteFile();
CloseExcel();
return true;
}
//builds the dataset to use
//creates the column names that will be written into and then written to the flat file
//SOME WILL JUST BE SPACES
private void CreateDataSet()
{
ds_taxes = new DataSet();
ds_taxes.Tables.Add("Taxes");
dt_taxes = new DataTable();
dt_taxes = ds_taxes.Tables["Taxes"];
dt_taxes.Columns.Add("Pr_Ward");
dt_taxes.Columns.Add("Pr_Block");
dt_taxes.Columns.Add("Pr_Map");
dt_taxes.Columns.Add("Pr_Parcel");
dt_taxes.Columns.Add("Pr_LeaseHold");
dt_taxes.Columns.Add("ParFill");
dt_taxes.Columns.Add("Stub");
dt_taxes.Columns.Add("Pa_Amt");
dt_taxes.Columns.Add("TOTFLG");
dt_taxes.Columns.Add("Pr_WardBATCH");
dt_taxes.Columns.Add("BSEQ");
dt_taxes.Columns.Add("TRANSNO");
dt_taxes.Columns.Add("TRANCD");
dt_taxes.Columns.Add("Pa_BatchDate_TD");
dt_taxes.Columns.Add("Pa_BatchDate_ED");
dt_taxes.Columns.Add("BUSDATE");
dt_taxes.Columns.Add("METH");
dt_taxes.Columns.Add("Pa_Amt2");
dt_taxes.Columns.Add("Payment_ID");
dt_taxes.Columns.Add("OWNSEQ");
dt_taxes.Columns.Add("Pr_OwnerInfo1");
}
//time to populate the dataset form the info from the ExcelSheet
private void PopulateDateSet()
{
//
i_xlRowTotal = 2;
while (xl_wrkSht.Cells.Range["A" + i_xlRowTotal].Value2 != null)
{
i_xlRowTotal++;
}
i_xlRowCount = 2;
i_xlRowTotal = i_xlRowTotal - 2;
for (i_dtRowCount = 0; i_dtRowCount < (i_xlRowTotal); ++i_dtRowCount)
{
//this is used to make conversions of the strings to add paddings, length modifiers, what have you...
//all that fun stuff
dr_taxes = dt_taxes.NewRow();
dr_taxes["Pr_Ward"] = Convert.ToString(xl_wrkSht.Cells.Cells.Range["P" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Block"] = Convert.ToString(xl_wrkSht.Cells.Range["Q" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Map"] = Convert.ToString(xl_wrkSht.Cells.Range["R" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Parcel"] = Convert.ToString(xl_wrkSht.Cells.Range["S" + (i_xlRowCount)].Value2);
dr_taxes["Pr_LeaseHold"] = Convert.ToString(xl_wrkSht.Cells.Range["T" + (i_xlRowCount)].Value2);
dr_taxes["ParFill"] = #" ";//12 spaces
dr_taxes["Stub"] = #" ";//10 spaces ALWAYS
dr_taxes["Pa_Amt"] = AppendAmt();
dr_taxes["TOTFLG"] = "N";
dr_taxes["Pr_WardBATCH"] = AppendWard();
dr_taxes["BSEQ"] = AppendBSEQ();
dr_taxes["TRANSNO"] = "000000000";
dr_taxes["TRANCD"] = "P";
dr_taxes["Pa_BatchDate_TD"] = AppendBatchDates();
dr_taxes["Pa_BatchDate_ED"] = AppendBatchDates();
dr_taxes["BUSDATE"] = #" "; //6 spaces
dr_taxes["METH"] = "Check";
dr_taxes["Pa_Amt2"] = AppendAmt();
dr_taxes["Payment_ID"] = AppendID();
dr_taxes["OWNSEQ"] = "000";
dr_taxes["Pr_OwnerInfo1"] = AppendOwner();
dt_taxes.Rows.Add(dr_taxes);
++i_xlRowCount;
i_RowCount = i_xlRowCount;
//RIGHT HERE IS WHERE I WANT TO CALL THE
Processing.bg_Taxes.ReportProgress() //method
}
}
I have tried Processing.bg_Taxes.ReportProgress(); but I get the Object reference is required for the non-static...method error (which I understand what that is.)
I have also looked at a lot of other Q&As on here about the using BackgroundWorkers however none of them seem to quite answer my question or I am just not getting it (which may be the issue as well).
My questions are, then: is there a way to call that method without making my BackgroundWorker static?
And with that: is there any problem with MAKING it static (I have always been told avoid static methods and what have you when writing code).
And finally: am I missing something in my logic here about how exactly I should be going about this? Is there another more "best practice" way?
Any help or advice is appreciated.
Thank you all in advance.
UPDATE
I ended up solving my problem by just some of the essential methods over to the Form class and altering my code from there. Just wanted to throw it out there and thank everyone for pointing in me in the right directions.
Related
im trying to do a program that read a string from a website e send it to another. the process to read string for the first works correctly, and also the function to send a string to the other works, but have problem when this function was called from the timer..
here is part of my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.WinForms.Internals;
namespace CodePinger
{
public partial class Form1 : Form
{
public bool login = true;
private static System.Timers.Timer TimerCheck;
public Form1()
{
InitializeComponent();
TimerCheck = new System.Timers.Timer(5000);
TimerCheck.Elapsed += new ElapsedEventHandler(CheckEvent);
TimerCheck.AutoReset = true;
CheckForIllegalCrossThreadCalls = false;
webBrowser1.ScriptErrorsSuppressed = true;
chromiumWebBrowser1.Load("https://firstwebsite.com");
webBrowser1.Navigate("http://secondwebsite.com");
}
private async void CheckEvent(Object source, ElapsedEventArgs e)
{
if (login) {
string script = "document.getElementById('SecondSDISP').innerText;";
JavascriptResponse jr = chromiumWebBrowser1.EvaluateScriptAsync(script).Result;
if (jr.Success)
{
if (jr.Result.ToString().Contains("01"))
{
label2.ForeColor = Color.Red;
label2.Text = jr.Result.ToString();
sendCode(jr.Result.ToString());
}
}
else
{
label2.ForeColor = Color.Black;
label2.Text = "no data";
}
label4.Text = timer.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
TimerCheck.Enabled = true;
TimerCheck.Start();
button2.Enabled = false;
}
public void sendCode(string code)
{
string msg = "";
if (code == "1") msg = "1 coda";
else msg = code.ToString() + " code";
var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
textarea.InnerHtml = msg;
textarea.Focus();
var allsvg = webBrowser1.Document.GetElementsByTagName("svg");
foreach (HtmlElement svg in allsvg)
{
if (svg.GetAttribute("className").Contains("-send"))
{
svg.InvokeMember("click");
break;
}
}
}
private void button4_Click(object sender, EventArgs e)
{
sendCode("1");
}
}
}
also after i started the timer, if i click to button4 to test the function, it works correctly. instead of when its called from timer
the error is:
System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()
at System.Windows.Forms.WebBrowser.get_Document()
at CodePinger.Form1.sendCode(String code) in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 105
at CodePinger.Form1.<CheckEvent>d__9.MoveNext() in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 63
the indicated line are:
105) var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
63) sendCode(jr.Result.ToString());
can someone explain me what is the problem?
Most likely your problem is you are trying to access the WebBrowser from a non-STA thread (aka the 'UI Thread')
When you use the button4_click handler your code is running on the STA Thread (by default), however, when a Time Event handler is called back it happens in a different thread (which is not the STA one) thus you will have problems invoking/accessing properties on ActiveX/Components (who reside in the STA thread) if you do not "invoke" back into the STA.
I recommend to take a look to the following SO Question: STA vs MTA for a technical explanation.
For solving the invoke problem look into the following SO Question: Automating the InvokeRequired code pattern
On the other hand the browser exposes a NavigateComplete event, you do not need to have a time checking when the page is loaded, just hook yourself to the event and wait for it after navigate, the DOM will be stable once this event fires.
I'm trying to create a library for C#, that would get the maximum number in a listbox.
Currently I am just trying the method in the program before creating the library. The following code is what I have:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace SPE16
{
public partial class FormExamStatistics : Form
{
List<double> ExamScores = new List<double>();
double highScore = 0;
public FormExamStatistics()
{
InitializeComponent();
}
private double HighScore(List<double> anyList) //return the highest score
{
return highScore = ExamScores.Max();
}
private void buttonAddFromFile_Click(object sender, EventArgs e)
{
StreamReader reader;
reader = File.OpenText("ExamScores.txt");
while (!reader.EndOfStream)
{
double Scores;
double.TryParse(reader.ReadLine(), out Scores);
ExamScores.Add(Scores);
listBoxScores.Items.Add(Scores);
labelHighScore.Text = highScore.ToString();
}
reader.Close();
/////////////
HighScore(ExamScores);
/////////////
}
}
}
Now, it is supposed to return the maximum value from the list created on top, which is populated by a text file "ExamScores.txt". This text file contains 60 (double) scores with a maximum number of 120.
The maximum number, should be 120, but it returns "0".
Now I need to make this as a method first, in order to create a (dll) library later.
What am I doing wrong?
you need to check your file because.NET Framework design guidelines recommend using the Try methods. Avoiding exceptions is usually a good ide
if (value == null)
{
return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider)
please post a your file content
did you tried,
private void buttonAddFromFile_Click(object sender, EventArgs e){
StreamReader reader;
reader = File.OpenText("ExamScores.txt");
while (!reader.EndOfStream){
double Scores;
double.TryParse(reader.ReadLine(), out Scores);
ExamScores.Add(Scores);
listBoxScores.Items.Add(Scores);
labelHighScore.Text = highScore.ToString();
}
reader.Close();
/////////////
HighScore(ExamScores);
/////////////
}
Proper sample for the question would be:
var highScore = 0;
labelHighScore.Text = highScore.ToString();
highScore = 42;
Written this way it clearly demonstrates that showing value first and only than changing it does not actually display updated value.
Fix: set value before showing it, likely labelHighScore.Text = highScore.ToString(); should be just moved to the end of the function.
Note that there are likely other problems in the code based on strange way HighScore returns result and how code completely ignores result of the function.
I have a simple form with a text box, a command button and a couple of timers. The only purpose of the form is to advise the user what is happening. The program executes all the code as required EXCEPT for the textbox changes. I know the code to implement the textbox changes is executed because the form and the command button properties change as required.
I have added this.refresh and this.textbox1.refresh to no avail.
I am new to C# and most of the time I do not have Visual Studios available, so your assistance would be most appreciated. I have read other posts on this topic and probably the answer has already been given, but I have not understood the solution.
The simplified code is given below:
//PROGRAM.CS
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using WindowsFormsApplication1;
namespace PostBinaryFile
{
static class Program
{
/// The main entry point for the application.
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(args));
}
}
}
//FORM1.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Web;
using System.Net;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string sUrl;
string sFileName;
string sCorNo;
public Form1(string[] args)
{
sUrl = args[0];
sFileName = args[1];
sCorNo = args[2];
InitializeComponent();
timer1.Enabled = true;
timer1.Start();
timer2.Enabled = true;
timer2.Start();
}
public void PostCode()
{
InitializeComponent();
string sToken;
string sPath;
const string boundary = "----WebKitFormBoundaryePkpFF7tjBAqx29L";
try
{
//Do all general code work here.
//Alter form to show successful post to web
this.button1.Visible = true;
this.button1.Enabled = true;
this.BackColor = System.Drawing.Color.FromArgb(189,194,241);
this.textBox1.Text = sCorNo + " Outlook file saved to FuseDMS."; // this code is executed but is not reflected on the Form
this.textBox1.BackColor= System.Drawing.Color.FromArgb(189,194,241); // this code is executed but is not reflected on the Form
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
timer1.Enabled = false;
PostCode();
}
private void timer2_Tick(object sender, EventArgs e)
{
timer2.Stop();
timer2.Enabled = false;
this.textBox1.Text = "Saving Message " + sCorNo + ".";
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
As #DavidG pointed out, you should not call InitializeComponent() periodically or even more then once, do it as the first thing in the constructor.
This is because any controls and properties that you add/set from the designer are created and initialized in this method.
Another thing to point out is Timer.Enabled = true and Timer.Start() effectively do the same thing
From: System.Windows.Forms.Timer.Enabled
Calling the Start method is the same as setting Enabled to true. Likewise, calling the Stop method is the same as setting Enabled to false.
Both timers namely timer1 and timer2 fire asynchronously and run on separate threads which are completely independent of each other. Even if timer2's tick event would be setting/refreshing the text appropriately through below code:
this.textBox1.Text = "Saving Message " + sCorNo + ".";
you can never say with guarantee that it will happen only after timer1's tick event has completed the execution of its callback method. In all likelyhood your above code is setting the text property of a dangling text box instance as your InitializeComponent function (being called from timer1's tick event) must be reinstantiating a new instance of all the form controls.
Your call to InitializeComponent function in PostCode method which gets called from tick event of timer1's tick event isn't right as it resets all the instances of form controls to new ones. It should be called only once in the constructor of the form. Just remove that piece of code and you should be good. Your PostCode function should actually look like this after you get rid of that piece of code:
public void PostCode()
{
string sToken;
string sPath;
const string boundary = "----WebKitFormBoundaryePkpFF7tjBAqx29L";
try
{
//Do all general code work here.
//Alter form to show successful post to web
this.button1.Visible = true;
this.button1.Enabled = true;
this.BackColor = System.Drawing.Color.FromArgb(189,194,241);
this.textBox1.Text = sCorNo + " Outlook file saved to FuseDMS."; // this code is executed but is not reflected on the Form
this.textBox1.BackColor= System.Drawing.Color.FromArgb(189,194,241); // this code is executed but is not reflected on the Form
}
I just want to say that I only joined stackoverflow a few weeks ago and everyone has been very helpful, thank you. I am down to my last two homework assignments for the semester. What I am trying to do right now is import the data I save to a text file from a program I wrote earlier. Basically the text file is named "client.txt" and the data in it looks like this
account#,firstname,lastname,balance
what I am trying to do now is write a windows form that will read the data in that text file and place it into appropriate corresponding text boxes in the form. Here is my code so far, I believe I am on the right track but I am having trouble because I need the program to do a openfiledialog so I can manually choose the client.txt file and then import the data. Right now I am getting an error "System.IO.StreamReader does not contain a constructor that takes 0 arguments"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Chapter_17_Ex.Sample_2
{
public partial class Form1 : Form
{
OpenFileDialog filechooser = new OpenFileDialog();
public Form1()
{
InitializeComponent();
}
private void btnImport_Click(object sender, EventArgs e)
{
StreamReader fileReader = new StreamReader();
string inputrecord = fileReader.ReadLine();
//string filename;
string[] inputfields;
if (inputrecord != null)
{
inputfields = inputrecord.Split(',');
txtAccount.Text = inputfields[0];
txtFirstName.Text = inputfields[1];
txtLastName.Text = inputfields[2];
txtBalance.Text = inputfields[3];
}
else
{
MessageBox.Show("End of File");
}
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
To use a StreamReader you need to construct it passing, at least, the filename to read.
This could be accomplished using the OpenFileDialog variable declared at the form global level
// Show the OpenFileDialog and wait for user to close with OK
if(filechooser.ShowDialog() == DialogResult.OK)
{
// Check if the file exists before trying to open it
if(File.Exists(filechooser.FileName))
{
// Enclose the streamreader in a using block to ensure proper closing and disposing
// of the file resource....
using(StreamReader fileReader = new StreamReader(filechooser.FileName))
{
string inputrecord = fileReader.ReadLine();
string[] inputfields;
....
// The remainder of your code seems to be correct, but a check on the actual
// length of the array resulting from the Split call should be added for safety
}
}
}
Notice that both the OpenFileDialog and the StreamReader are complex objects that have many properties and different ways to work. You really need to look at their constructors and properties list in the MSDN documentation to exploit their full functionality
Am new to programming, so please assist as much as possible!
Recently, im tasked to do a CRUD windows form application using C# & MS access.
In my update function, i face one of the following errors which im not sure why..
My data are not able to be updated either.
Error: ArgumentException was unhandled
Input string was not in a correct format.Couldn't store
in staff_id Column. Expected type is
Int32.
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AcuzioSapp.AcuzioSecureStore_DatabaseDataSetTableAdapters;
namespace AcuzioSapp
{
public partial class Update_Client : Form
{
private DataRow row;
private ClientTableAdapter adapter;
public Update_Client(DataRow row, ClientTableAdapter adapter)
{
InitializeComponent();
this.row = row;
this.adapter = adapter;
textBox_id1.Text = Convert.ToString(row["c_id"]);
textBox_name1.Text = Convert.ToString(row["c_name"]);
textBox_address1.Text = Convert.ToString(row["c_address"]);
textBox_cinfo1.Text = Convert.ToString(row["c_contactinfo"]);
textBox_pinfo1.Text = Convert.ToString(row["profile_info"]);
textBox_refno1.Text = Convert.ToString(row["c_8digitrefno"]);
textBox_staffid1.Text = Convert.ToString(row["staff_id"]);
}
private void button_close_Click(object sender, EventArgs e)
{
Close();
}
private void button_update_Click(object sender, EventArgs e)
{
row["c_name"] = "textBox_name1";
row["c_address"] = "textBox_address1";
row["c_contactinfo"] = "int.Parse(textBox_cinfo1)";
row["c_8digitrefno"] = "(textBox_pinfo1)";
row["profile_info"] = "textBox_refno1";
row["staff_id"] = "int.Parse(textBox_staffid1)";
adapter.Update(row);
}
}
}
Appreciated for help and explanation thankyou.
Thats because of your column is declared integer in your Access database and you try to insert a String value in it. And I also think you will not get proper value in your specified table because you update your columns by constant string (row["profile_info"] = "textBox_refno1";), this will insert textBox_refno1 into profile_info column not TextBox value.
Try this :
row["staff_id"] = Convert.ToInt32(textBox_staffid1.Text);
Update:
Copy and paste following code, and you will never have any issue:
private void button_update_Click(object sender, EventArgs e)
{
row["c_name"] = textBox_name1.Text;
row["c_address"] = textBox_address1.Text;
row["c_contactinfo"] = int.Parse(textBox_cinfo1.Text);
row["c_8digitrefno"] = textBox_pinfo1.Text;
row["profile_info"] = textBox_refno1.Text;
row["staff_id"] = int.Parse(textBox_staffid1.Text);
adapter.Update(row);
MessageBox.Show("Data has been updated");
}
Hope this help.
row["c_name"] = textBox_name1.Text;
row["c_address"] = textBox_address1.Text;
...
int val;
if(int.TryParse(textBox_staffid1.Text, out val))
{
row["staff_id"] = val;
}
I consider, that text in your textbox not in correct format.