ArguementOutOfRangeException was unhandled error - c#

i'm very new to programming and c#. here i'm having ArguementOutOfRangeException. i want to add a new data row to the datagridview every time when click the button. so i used a variable "i" to increase the value one by one and change the row value when i use "0" which means
dataGridView2.Rows[0].Cells[0].Value = textBox1.Text.ToString();
instead of "i" the first row fills but when use "1" which means
dataGridView2.Rows[1].Cells[0].Value = textBox1.Text.ToString();
the exception comes. what is the right way to do such a thing ?
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public SqlConnection conn;
public int i = 0;
private void Form2_Load(object sender, EventArgs e)
{
conn = new SqlConnection("Data Source=.\\SQLEXPRESS; Integrated Security=sspi; Initial Catalog=student");
conn.Open();
}
private void button1_Click(object sender, EventArgs e)
{
string Sqlstr = "insert into student(name, pw)values(#name,#pw)";
SqlCommand cmd = new SqlCommand(Sqlstr, conn);
cmd.Parameters.AddWithValue("#name", textBox1.Text);
cmd.Parameters.AddWithValue("#pw", textBox2.Text);
if (cmd.ExecuteNonQuery() > 0)
{
i++;
DataGridView dataGridView1 = new DataGridView();
dataGridView2.Rows[i].Cells[0].Value = textBox1.Text.ToString();
dataGridView2.Rows[i].Cells[1].Value = textBox2.Text.ToString();
}
label1.Text = Convert.ToString(i);
}
}
}

You don't have to define a new DataGridView each time on a button click, I believe you want to add a new row in your existing DataGridView after the insert in database. You can do:
if (cmd.ExecuteNonQuery() > 0)
{
DataGridViewRow row = (DataGridViewRow)dataGridView2.Rows[0].Clone();
row.Cells[0].Value = textBox1.Text.ToString();
row.Cells[1].Value = textBox2.Text.ToString();
dataGridView2.Rows.Add(row);
}

You have to add new rows before you try writing in them. Use dataGridView2.Rows.Add( something ), check out the Add method.

Related

Delete a row from a table, specified by the user, with the click of a button in C#

I am using Visual Studio 2019 Winforms C# .NET Framework and in the Winforms project, there is a textbox and a button.
When I type a parameter name in the textbox and click the button, I want to delete the row from the table called "Serial_Key".
private void button1_Click(object sender, EventArgs e)
{
string mainconn = ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString;
SqlConnection sqlconn2 = new SqlConnection(mainconn);
string sqlquery = "select * from [dbo].[Serial-Keys] where Serial_Key=#Serial_Key";
sqlconn2.Open();
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn2);
sqlcomm.Parameters.AddWithValue("#Serial_Key", SerialKeyBox.Text);
SqlDataAdapter sda = new SqlDataAdapter(sqlcomm);
DataTable dt = new DataTable();
sda.Fill(dt);
sqlcomm.ExecuteNonQuery();
if (dt.Rows.Count > 0)
{
Cursor.Current = Cursors.WaitCursor;
try
{
}
catch (Exception)
{
}
Cursor.Current = Cursors.Default;
}
else
{
MessageBox.Show("Invalid Serial Key!");
label7.Text = "Serial Key Rejected...";
}
}
Change your select statement to a delete statement and remove all the DataAdaptor stuff as thats only required if you are querying records.
private void button1_Click(object sender, EventArgs e)
{
string mainconn = ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString;
SqlConnection sqlconn2 = new SqlConnection(mainconn);
// Use a Delete statement, not a select
string sqlquery = "delete from [dbo].[Serial-Keys] where Serial_Key = #Serial_Key";
sqlconn2.Open();
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn2);
// Construct the parameter yourself with the correct datatype and precision
sqlcomm.Parameters.Add(new SqlParameter("#Serial_Key", SqlDbType.VarChar, 32) { Value = SerialKeyBox.Text });
// Remove all the DataAdaptor stuff
// ExecuteNonQuery returns the rows affected
int numberOfRecords = sqlcomm.ExecuteNonQuery();
if (numberOfRecords > 0)
{
// Any code to run on an effective delete
}
else
{
MessageBox.Show("Invalid Serial Key!");
label7.Text = "Serial Key Rejected...";
}
}
If you install Dapper then your code becomes very simple:
private async void button1_Click(object sender, EventArgs e)
{
using(var c = new SqlConnection(_connStr))
await c.ExecuteAsync("DELETE FROM dbo.[Serial-Keys] WHERE serial_key = #sk", new { sk = SerialKeyBox.Text });
}
And, bonus, it doesn't jam your UI while it runs queries
I recommend you put that string mainconn = ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString; into a class level variable called _connStr instead, to help tidy things up
http://dapper-tutorial.net (no affiliation)

Using SAME Textbox to search and insert data in dataGridView

I have a Textbox with which I want to be able to Search and Insert data into Table. Insert works fine with one exception: When I try to Insert data that isn't already in DB(it's searching while I'm typing) it gives me:
"Exception User-Unhandled System.NullReferenceException: 'Object
reference not set to an instance of an object.'
System.Windows.Forms.DataGridView.CurrentRow.get returned null.
I think I'm missing something in the Search code.
//UPDATE: All of the code.// This is my Insert and Search code:
namespace UDDKT
{
public partial class FrmGlavna : Form
{
DataSet ds = new DataSet();
SqlDataAdapter DaDavaoci = new SqlDataAdapter();
SqlDataAdapter DaAkcije = new SqlDataAdapter();
SqlConnection cs = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UDDKT.mdf;Integrated Security=True");
public FrmGlavna()
{
InitializeComponent();
}
//Popunjava DataGridViews sa podacima iz baze
private void FrmGlavna_Load(object sender, EventArgs e)
{
SqlCommand SlctDavaoci = new SqlCommand("SELECT * FROM Davaoci ORDER BY DavaocID DESC", cs);
DaDavaoci.SelectCommand = SlctDavaoci;
DaDavaoci.Fill(ds, "TblDavaoci");
SqlCommand SlctAkcije = new SqlCommand("SELECT * FROM AkcijaDDK", cs);
DaAkcije.SelectCommand = SlctAkcije;
DaAkcije.Fill(ds, "TblAkcije");
DgDavaoci.DataSource = ds.Tables["TblDavaoci"];
}
//Povezuje DataGridViews Davaoca i Akcija
private void DgDavaoci_SelectionChanged(object sender, EventArgs e)
{
ds.Tables["TblAkcije"].DefaultView.RowFilter = "DavaocID =" + DgDavaoci.CurrentRow.Cells["DavaocID"].Value;
DgAkcije.DataSource = ds.Tables["TblAkcije"];
}
//Osvježava DataGridView nakon unosa/izmjene/brisanja podataka u bazu
private void RefreshTable()
{
SqlConnection cs = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UDDKT.mdf;Integrated Security=True");
String query = "SELECT * FROM Davaoci ORDER BY DavaocID DESC";
SqlCommand cmd = new SqlCommand(query, cs);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
DgDavaoci.DataSource = dt;
}
//Čisti TextBox nakon upisa/izmjene/brisanja podataka u bazu
public void ClearTxtBx()
{
TxtIme.Clear();
TxtPrezime.Clear();
TxtTezina.Clear();
TxtAdresa.Clear();
TxtBrojTel.Clear();
TxtBrojLK.Clear();
}
//Upis podataka u Tabelu Davaoci
private void BtnDodajDavaoca_Click(object sender, EventArgs e)
{
String query = "INSERT INTO Davaoci (Ime,Prezime,Pol,DatumRodjenja,KrvnaGrupa,Tezina,Adresa,BrojTel,BrojLK) VALUES (#Ime, #Prezime, #Pol, #DatumRodjenja, #KrvnaGrupa, #Tezina, #Adresa, #BrojTel, #BrojLK)";
using (SqlConnection cs = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UDDKT.mdf;Integrated Security=True"))
using (SqlCommand command = new SqlCommand(query, cs))
{
command.Parameters.Add("#Ime", SqlDbType.NVarChar).Value = TxtIme.Text;
command.Parameters.Add("#Prezime", SqlDbType.NVarChar).Value = TxtPrezime.Text;
command.Parameters.Add("#Pol", SqlDbType.NChar).Value = TxtPol.Text;
command.Parameters.Add("#DatumRodjenja", SqlDbType.Date).Value = TxtDatumRodjenja.Text;
command.Parameters.Add("#KrvnaGrupa", SqlDbType.VarChar).Value = TxtKrvnaGrupa.Text;
command.Parameters.Add("#Tezina", SqlDbType.Float).Value = TxtTezina.Text;
command.Parameters.Add("#Adresa", SqlDbType.NVarChar).Value = TxtAdresa.Text;
command.Parameters.Add("#BrojTel", SqlDbType.NVarChar).Value = TxtBrojTel.Text;
command.Parameters.Add("#BrojLK", SqlDbType.NVarChar).Value = TxtBrojLK.Text;
cs.Open();
command.ExecuteNonQuery();
cs.Close();
RefreshTable();
ClearTxtBx();
}
}
//Pretraga postojećih Davalaca
private void TxtIme_TextChanged(object sender, EventArgs e)
{
(DgDavaoci.DataSource as DataTable).DefaultView.RowFilter = string.Format("Ime LIKE '{0}%'", TxtIme.Text);
}
}
}
}
Here is the MockUp of the Form before I begin to type/search/insert Data that isn't already in the Table (First Textbox*).
And after I start typing Name(Име) that starts with an "A" (name that isn't already in the Table).
I want to Search DB for that Column, but if there aren't any existing names, I want to be able to continue typing (without interuption) so that I can Insert new data into table.
DgDavaoci.CurrentRow in your DgDavaoci_SelectionChanged method is null, so attempting to access DgDavaoci.CurrentRow.Cells["DavaocID"] throws the NullReferenceException. The reason, best I can tell, is as follows:
You begin to type a value into your text box, a value that happens not to be found in the data set. As you type, you cause the TxtIme_TextChanged method to execute. It filters according to your search, and since the value is not found, it filters out every row in the set. Here's the important part: whenever the data set is filtered, it has the possibility of causing DgDavaoci_SelectionChanged to execute. Since the selection changed from the first row to no row at all (since there are no filtered rows to display), this method does execute. Now, when the method attempts to access the current row, there is no current row, and so we get a null here. Attempting to access a field of null throws the exception you're getting.
How can you fix this behavior? A simple null-check in DgDavaoci_SelectionChanged should do the trick. It looks to me like you can simply return from that method if(DgDavaoci.CurrentRow == null), or you can code in additional behavior. Just perform a check so that you don't reference the null object.
Probably the filter inside TxtIme_TextChanged is causing the DataGridView's SelectionChanged event to fire and the code is entering DgDavaoci_SelectionChanged. The exception indicates that DgDavaoci.CurrentRow is null, so you'll need to handle the case where DgDavaoci.CurrentRow is null in DgDavaoci_SelectionChanged.
A simple way to deal with this would be to just check DgDavaoci.CurrentRow is null and return from the function if that evaluates to true.
private void DgDavaoci_SelectionChanged(object sender, EventArgs e)
{
if (DgDavaoci.CurrentRow is null)
{
return;
}
ds.Tables["TblAkcije"].DefaultView.RowFilter = "DavaocID =" +
DgDavaoci.CurrentRow.Cells["DavaocID"].Value;
DgAkcije.DataSource = ds.Tables["TblAkcije"];
}
It looks like you might have a second DataGridView (DgAkcije) that is designed to show the details of the currently selected row in DgDavaoci. So, another approach might be to just clear DgAkcije if DgDavaoci.CurrentRow is null.
private void DgDavaoci_SelectionChanged(object sender, EventArgs e)
{
if (DgDavaoci.CurrentRow is null)
{
DgAkcije.DataSource = null; //I'm not 100% sure this will work, I haven't tested it.
return;
}
ds.Tables["TblAkcije"].DefaultView.RowFilter = "DavaocID =" +
DgDavaoci.CurrentRow.Cells["DavaocID"].Value;
DgAkcije.DataSource = ds.Tables["TblAkcije"];
}
Ultimately, however, you'll have to decide what you want to happen when DgDavaoci_SelectionChanged is called but DgDavaoci.CurrentRow is null.
Solution if anyone else is interested:
//Povezuje DataGridViews Davaoca i Akcija
private void DgDavaoci_SelectionChanged(object sender, EventArgs e)
{
if (DgDavaoci.CurrentRow != null)
{
ds.Tables["TblAkcije"].DefaultView.RowFilter = "DavaocID =" + DgDavaoci.CurrentRow.Cells["DavaocID"].Value;
DgAkcije.DataSource = ds.Tables["TblAkcije"];
}
}

Update datagridview from SQL in the form close event

I have a form with a dataGridView1 that is updated from SQL database.
What i am trying to do is: when the user presses the Close button I am checking a variable and if condition is true then I cancel the from close (e.Cancel = true;) and i want to display some data in the datagrid.
Whatever I do the grid is not updating. I am calling a "private void update()" to update the grid from SQL but after I cancel the form close event but it does not seem to work.
I have tried refreshing the form, refreshing the datagrid with no result.
After the form_Close even finishes, and the datagrid is empty, if i press a button that calls the same "private void update()" it works and the data is shown in the datagrid.
Thank you for your help.
EDIT1: to give you more details
I tried the code on FormClosing but I get no result.
The code I'm using is:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
getdata_fromSQL();//this private void gets some data from sql into the datagrid
if (dataGridView1.RowCount > 0)//check if i have at least one row retreved
{
// Cancel the Closing event and tell the user
MessageBox.Show("Please check the data before leaving.");
e.Cancel = true;
getdata_fromSQL();// retrieve the data again for the user to see (this part is not working
}
}
This is how the data is retrieved.
private void getdata_fromSQL()
{
SqlConnection con = new SqlConnection("connection string"); //defining connection
con.Open();
string sql_command = "Select * from Test_Table where [Check] is null";
SqlCommand command = new SqlCommand(sql_command, con); // defining the command
DataSet set = new DataSet("SQL_table");
SqlDataAdaptersda = new SqlDataAdapter(command); //defining the adapter and make it accept changes
sda.AcceptChangesDuringFill = true;
sda.AcceptChangesDuringUpdate = true;
set.Clear(); //just to make sure my adapter is empty
cmdBuilder = new SqlCommandBuilder(sda); //creating the command builder so I can save the changes
sda.Fill(set, "SQL_table"); // fill the dataset
dataGridView1.DataSource = set;
dataGridView1.DataMember = "SQL_table"; //fill datagrid
dataGridView1.CellValueChanged -= dataGridView1_CellValueChanged;
dataGridView1.CellValueChanged += dataGridView1_CellValueChanged; //look for cell value changed (I am using this in other scope)
}
After I cancel the close and try to update the datagrid again, it remains blank.
EDIT2: #Gami
your code does this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (i == 1)
{
MessageBox.Show("Hello");
e.Cancel = true;
getRefresh();
}
}
and your refresh is this:
private void getRefresh()
{
SqlConnection con = new SqlConnection(#"user id=testuser;" +
"password=testpass;Data Source=SERVER;" +
// "Trusted_Connection=yes;" +
"Initial Catalog=Partner_database; " +
"connection timeout=30"); //defining connection
con.Open();
SqlCommandBuilder cmdBuilder;
string sql_command = "Select * from Test_table where [Check] is null";
SqlCommand command = new SqlCommand(sql_command, con); // defining the command
DataSet set = new DataSet("SQL_table");
SqlDataAdapter sda = new SqlDataAdapter(command); //defining the adapter and make it accept changes
sda.AcceptChangesDuringFill = true;
sda.AcceptChangesDuringUpdate = true;
set.Clear(); //just to make sure my adapter is empty
cmdBuilder = new SqlCommandBuilder(sda); //creating the command builder so I can save the changes
sda.Fill(set,"SQL_table"); // fill the dataset
dataGridView1.DataSource = set;
dataGridView1.DataMember = "SQL_table"; //fill datagrid
}
My code is the one above. We are both using the FormClosing event, we both cancel the close process, and then call the refresh.
This is the SQL table:
This is the datasource for my datagrid:
Try to write code in Form1_FormClosing() event of form
example is
namespace canceldemo
{
public partial class Form1 : Form
{
int i = 1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (i == 1)
{
MessageBox.Show("Hello");
e.Cancel = true;
}
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = (i+10).ToString();
}
}
}
I have found the issue.
Looks like it was a mistake on my side, I still don't know why is not working the way it is, but know the cause.
I am using code to get the logged user name from Windows, and when i filter the SQL table i filter on the user as well.
This is the code to retrieve the user:
private string getUserDisplayName()
{
var username = new StringBuilder(1024);
uint userNameSize = (uint)username.Capacity;
// try to get display name and convert from "Last, First" to "First Last" if necessary
if (0 != GetUserNameEx(3, username, ref userNameSize))
return Regex.Replace(username.ToString(), #"(\S+), (\S+)", "$2 $1");
// get SAM compatible name <server/machine>\\<username>
if (0 != GetUserNameEx(2, username, ref userNameSize))
{
IntPtr bufPtr;
try
{
string domain = Regex.Replace(username.ToString(), #"(.+)\\.+", #"$1");
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domain);
DomainController dc = DomainController.FindOne(context);
if (0 == NetUserGetInfo(dc.IPAddress,
Regex.Replace(username.ToString(), #".+\\(.+)", "$1"),
10, out bufPtr))
{
var userInfo = (USER_INFO_10)Marshal.PtrToStructure(bufPtr, typeof(USER_INFO_10));
return Regex.Replace(userInfo.usri10_full_name, #"(\S+), (\S+)", "$2 $1");
}
}
finally
{
NetApiBufferFree(out bufPtr);
}
}
return String.Empty;
}
In my FormClosing block i am calling this private void and use this as filter to sql.
user_name = getUserDisplayName();
string sql_command = "Select * from Test_table where [Check] is null and [User Name] = '" + user_name + "'";
When removing the getUserDisplayName() call it works. When i call it it does not refresh the grid even if it runs with no error.
Does it cut my connections when i press the close button? I think this is another question and here is off topic.

How can I show my data from database in Multi-line TextBox line by line?

I have tried below code. It is run successfully but showing result as "System.Data.DataView" in txtQueue(Text box) but not the data.
try
{
AddURL objAddurls = new AddURL();
objAddurls.ExecuteSql("select sURL from addurl where iStatus=1 AND iLicenseID='" + CommonMethods.iLicenseID + "'");
txtQueueURLs.Text = objAddurls.DefaultView.ToString();
}
catch (Exception ee)
{
}
could any body tell me please what's wrong with this code or suggest me new code?
thanks in Advance.
How can I show my data from database in Multi-line TextBox line by
line?
There are few ways to retrieve data form database and this is jut one of them, what method will you choose is not important.
Writing data to a textBox, line by line, can be achieved by setting textBox.Multiline property to true and adding Environment.NewLine to textBox.Text every time you need new line.
Here is the example code that might help you:
using System.Data.SqlClient;
namespace StackTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string connectionString = #"Data Source=(localdb)\Projects;Initial Catalog=DbTest;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False";
string selectString = "select * from TblTest";
textBox1.Multiline = true;
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(selectString,conn);
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
textBox1.Text += rdr[0];
textBox1.Text += rdr[1];
//...
textBox1.Text += Environment.NewLine;
}
conn.Close();
}
}
}
You are calling the ToString method on DataView.ToString() which returns the name of the component. I think you want to iterate through the rows within the DefaultView and assign the TextBox value to that.
StringBuilder sb = new StringBuilder();
foreach (DataRowView rowView in objAddurls.DefaultView)
{
DataRow row = rowView.Row;
// build a string from your row //
}
txtQueueURLs.Text = sb.ToString()

How do I read data from a database and display it in a TextBox?

I try to get one data column from a MS-Access table and display it in a TextBox like this
public partial class Form1 : Form
{
public OleDbConnection database;
public Form1()
{
InitializeComponent();
}
private OleDbConnection Database_Connection;
private void Open_Database_button_Click(object sender, EventArgs e)
{
Database_Connection = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="test.mdb");
OleDbCommand Command = new OleDbCommand(
" SELECT top 1 * from test", Database_Connection);
Database_Connection.Open();
OleDbDataReader DB_Reader = Command.ExecuteReader();
// How can I display the column in TextBox?
}
...
}
Try to change your Open_Database_button_Click in this way:
private void Open_Database_button_Click(object sender, EventArgs e)
{
using(OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb" ))
using(OleDbCommand Command = new OleDbCommand(" SELECT top 1 * from test", con))
{
con.Open();
OleDbDataReader DB_Reader = Command.ExecuteReader();
if(DB_Reader.HasRows)
{
DB_Reader.Read();
textbox1.Text = DB_Reader.GetString("your_column_name");
}
}
}
What I have changed/added:
Removed the global var DataBase_Connection
Added using to the Disposable objects, so they will automatically
closed when no more needed
Added check on DB_Reader.HasRows to exclude empty results from the
query
Added setting of the text property of the textbox with the value of
one of your columns

Categories

Resources