My combobox doesn't show data from database - c#

my combo box needs to show data from my database but it shows empty.
here you have my code that i'm working on, visual studio dont show any error, but combobox shows empty, any tips ?
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
{
SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\Documents\basededadospap.mdf;Integrated Security=True;Connect Timeout=30");
try
{
cn.Open();
string query = "select * from fornecedor where nomefornecedor='" + comboBox1 + "'";
SqlCommand createCommand = new SqlCommand(query, cn);
SqlDataReader dr = createCommand.ExecuteReader();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

ExecuteReader will return a reader which you then have to use to read back your results row by row, and populate your combo box accordingly.
For example, if you have a (non nullable) string column named "MyItem" in your fornecedor table, you would write something like this:
using (SqlDataReader dr = createCommand.ExecuteReader())
{
int myItemOrdinal = dr.GetOrdinal("MyItem");
List<object> comboBoxRows = new List<object>();
while (dr.Read())
{
string myItem = dr.GetString(myItemOrdinal);
comboBoxRows.Add(myItem);
}
}
comboBox1.BeginInvoke(() => comboBox1.Items.AddRange(comboBoxRows.ToArray()));
The last row populates the combo box on the UI thread, assuming reading the rows from the database is done on another thread (which is something you'd want to do to keep your UI responsive).

Related

How to get the data when I select a datagridview cell or column

I have 2 datagridview controls in a Windows Forms application.
I would like to get the info of a person when I select first datagridview cell or row to next datagridview:
try
{
ConnectionStringSettings consettings = ConfigurationManager.ConnectionStrings["attendancemanagement"];
string connectionString = consettings.ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
con.Open();
adap3 = new SqlDataAdapter(#"SELECT Date,Attendance,Remarks FROM dailyattendance where employee_id='"+DailyGV.CurrentRow+"'", con);
ds3 = new DataSet();
adap3.Fill(ds3, "dailyattendance");
dataGridView1.DataSource = ds3.Tables[0];
}
Im trying the above code. But it's not working.
I'm not too sure what DailyGV.CurrentRow is but basically you can use the RowHeaderMouseClick...see MSDN documentation. To use it, hook an event handler to it when initializing the form components (you can use VS designer as well...
dataGridView1.RowHeaderMouseClick += dataGridView1_RowHeaderMouseClick;
void dataGridView1_RowHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
}
this event handler will get fired everytime you select a row header in the DataGridView control which will pass information about the event through an instance of the DataGridViewCellMouseEventArgs class (see MSDN documentation). This argument has a RowIndex property that provides the index of the row clicked which you can use to retrieve the values of the cells in that row...including the person id (if provided)...for example...
void dataGridView1_RowHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
string personId = dataGridView1.Rows[e.RowIndex].Cells["PersonId"].Value;
//TODO: implement your own query to retrieve data for that person id
}
notice that you need to provide a proper column name when access the cells collection indexer...Cells["columnName"]
I will not give any description about the solution because Leo and Arsalan Bhatti has already suggested the solution. I am just telling you how your code should looks like and how it should be written.
string connectionString = consettings.ConnectionString;
using (SqlConnection con = new SqlConnection(connectionString))
{
try
{
con.Open();
string empID = DailyGV.CurrentRow.Cells["employee_id"].Value.ToString();
SqlCommand Cmd = con.CreateCommand();
Cmd.CommandText = "SELECT Date,Attendance,Remarks FROM dailyattendance where employee_id=#employee_id";
Cmd.Parameters.Add("#employee_id", SqlDbType.Int).Value = Int32.Parse(empID);
adap3 = new SqlDataAdapter(Cmd);
DataTable dt = new DataTable();
adap3.Fill(dt);
dataGridView1.DataSource = dt;
con.Close();
}
catch
{}
}
try
{
cn.Open();
string query = "select employee_id,Employee_Name,Image_of_Employee from Employee_Details where employee_id='" + dataGridView1.SelectedCells[0].Value.ToString() + "'";
SqlCommand cmd = new SqlCommand(query, cn);
SqlDataReader sdr;
sdr = cmd.ExecuteReader();
if (sdr.Read())
{
string aa = (string)sdr["employee_id"];
string bb = (string)sdr["employee_name"];
txtEmployeeID.Text = aa.ToString();
txtnameofemployee.Text = bb.ToString();
byte[] img=(byte[])sdr["Image_of_employee"];
MemoryStream ms=new MemoryStream(img);
ms.Seek(0,SeekOrigin.Begin);
pictureBox1.Image=Image.FromStream(ms); cn.Close();
}
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
You are passing the current row's index as employee id in SELECT query. Pass employee id for the selected record. Then it will work fine.

C# Mysql multiple queries

Im trying to build up a little status-tool. I need to get results of multiple queries (about 4-5). The general connection-setup and 'how-to-read-data' is already done but I cant figure out how the another query executed.
Everything I found while searching for it is for the SqlClient. Im totally overcharged with this.
Here is my code so far (be patient, im a newbie to this):
private void button1_Click(object sender, EventArgs e)
{
if(listView1.Items.Count > 1)
{
listView1.Items.Clear();
}
var listMember = new List<string>{};
var listOnline = new List<string>{};
// SQL PART //
string connString = "Server=10*****;Port=3306;Database=e***;Uid=e***;password=********************;";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = "SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC";
try
{
conn.Open();
}
catch (Exception ex)
{
listView1.Items.Add("Error: " + ex);
}
MySqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
listMember.Add(reader["fullname"].ToString());
listOnline.Add(reader["online"].ToString());
}
conn.Close();
// SQL ENDING //
// SET ENTRIES TO LISTVIEW //
int counter = 0;
foreach(string member in listMember)
{
ListViewItem item = new ListViewItem(new[] { member, listOnline.ElementAt(counter) });
item.ForeColor = Color.Green;
listView1.Items.Add(item);
counter++;
}
}
Im not really sure how the design/layout will look like in the end, so I would like to just append the results to lists in the sql-part to process the data later out of the lists.
Do I really have to setup a complete new connection after conn.Close()? Or is there any other way? I can just imagine: 5 queries with their own connection,try,catch and 2 loops... this will get about 100-200 lines just for getting the results out of 5 queries. Isnt that a bit too much for such an easy thing?
Hope for some help.
Greetings.
According to the new comments my latest code:
Top:
public partial class Form1 : Form
{
public static string connString = "Server=10****;Port=3306;Database=e****;Uid=e****;password=****;";
public Form1()
{
InitializeComponent();
MySqlConnection conn = new MySqlConnection(connString); // Error gone!
}
Body part:
public void QueryTwoFields(string s, List<string> S1, List<string> S2)
{
try
{
MySqlCommand cmd = conn.CreateCommand(); // ERROR: conn does not exist in the current context.
cmd.CommandType = CommandType.Text;
string command = s;
cmd.CommandText = command;
MySqlDataReader sqlreader = cmd.ExecuteReader();
while (sqlreader.Read())
{
S1.Add(sqlreader[0].ToString());
S2.Add(sqlreader[1].ToString());
}
sqlreader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
if(listView1.Items.Count > 1)
{
listView1.Items.Clear();
}
var listMember = new List<string>{};
var listOnline = new List<string>{};
using (conn) // ERROR: conn does not exist in the current context.
{
conn.Open();
///...1st Query
QueryTwoFields("SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC",listMember,listOnline);
//...2nd query
//QueryTwoFields("your new Select Statement", otherList, otherList);
}
}
You don't have to close connection every time you execute one query rarher than close the sqlreader assigned to that connection. Finally when all of your queries have been executed you close the connection. Consider also the use of using:
You cal also define a method for execution your Query in order for your code not to be repetive:
public void QueryTwoFields(string s, List<string> S1, List<string> S2)
///Select into List S1 and List S2 from Database (2 fields)
{
try
{
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
string command = s;
cmd.CommandText = command;
MySqlDataReader sqlreader = cmd.ExecuteReader();
while (sqlreader.Read())
{
S1.Add(sqlreader[0].ToString());
S2.Add(sqlreader[1].ToString());
}
sqlreader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
if(listView1.Items.Count > 1)
{
listView1.Items.Clear();
}
var listMember = new List<string>{};
var listOnline = new List<string>{};
// SQL PART //
using (conn)
{
conn.Open();
///...1st Query
QueryTwoFields("SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC",listmember,listonline)
//...2nd query
QueryTwoFields("your new Select Statement",myOtherList1,myOtherlist2)
....
}
}
EDIT :
Take in mind you cant define QueryTwoFields method inside button handler. You must define it outside (see code above).
Also Define your connection data in the start of the programm:
namespace MyProject
{
/// <summary>
/// Defiine your connectionstring and connection
/// </summary>
///
public partial class Form1 : Form
{ public static string connString = "Server=10*****;Port=3306;Database=e***;Uid=e***;password=********************;";
MySqlConnection conn = new MySqlConnection(connString);
.........
Datatables are fantastic
Using a data table is a nice way to do both read and write. And it comes with the luxury of eveything you can do with a datatable - like asssigning it directly to a datagrid control, sorting, selecting and deleting while disconnected.
The sample below assumes a MySqlConnection conection property managed by calls to your own OpenConnection() and CloseConnection() methods not shown.
Simple datatable read demo:
public DataTable Select(string query = "")
{
//Typical sql: "SELECT * FROM motorparameter"
DataTable dt = new DataTable();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
dt.Load(dataReader);
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return data table
return dt;
}
else
{
return dt;
}
}
In case of writing back the datatable to the database - supply the SQL you used in the read (or would have used to read to the data table):
public void Save(DataTable dt, string DataTableSqlSelect)
{
//Typically "SELECT * FROM motorparameter"
string query = DataTableSqlSelect;
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand mySqlCmd = new MySqlCommand(query, connection);
MySqlDataAdapter adapter = new MySqlDataAdapter(mySqlCmd);
MySqlCommandBuilder myCB = new MySqlCommandBuilder(adapter);
adapter.UpdateCommand = myCB.GetUpdateCommand();
adapter.Update(dt);
//close Connection
this.CloseConnection();
}
else
{
}
}
The neat thing the datatable is extremely flexible. You can run your own selects against the table once it contains data and before writing back you can set or reset what rows needs updating and by default the datatable keeps track of what rows you update in the table. Do not forget primary key column(s) for all tables in the db.
For multiple queries consider if possible using a join between the database tables or same table if data related or use a UNION sql syntax if column count and type of data is the same. You can allways "create" your extra column in the select to differ what data comes from what part of the UNION.
Also consider using CASE WHEN sql syntax to conditionally select data from different sources.

Refreshing the combobox after inserting data in mysql c#

Hello so i want to refresh my combobox after i add or delete data from it now if i add data it doesnt get refreshed i have to rerun the program to see the changes but i want to get it refresh in the time i add the data..
the code when i add data:
private void button5_Click(object sender, EventArgs e)
{
MySqlConnection dataConnection = new MySqlConnection();
dataConnection.ConnectionString = "datasource=localhost;port=3306;username=root;password=";
dataConnection.Open();
MySqlTransaction transakcija = dataConnection.BeginTransaction();
MySqlCommand dataCommand = new MySqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Transaction = transakcija;
try
{
dataCommand.CommandText = "Insert INTO filmi.film (film) VALUES ('" + this.tB_Dodaj.Text + "')";
dataCommand.CommandType = CommandType.Text;
dataCommand.ExecuteNonQuery();
transakcija.Commit();
MessageBox.Show("You added a new movie!");
}
catch (Exception eks)
{
transakcija.Rollback();
MessageBox.Show("Movie couldnt be added!!\n" + eks.Message);
}
finally
{
dataCommand.Connection.Close();
}
}
and with each insert the data gets displayed in the combobox but only when i rerun the program
this is how i fill combobox:
void Fillcombo()
{
string constring = "datasource=localhost;port=3306;username=root;password=";
string Query = "SELECT * FROM filmi.film ;";
MySqlConnection conDataBase = new MySqlConnection(constring);
MySqlCommand cmdDataBase = new MySqlCommand(Query, conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
string sName = myReader.GetString("film");
comboBox1.Items.Add(sName);
comboBox2.Items.Add(sName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
i have to rerun the program to see the changes but i want to get it
refresh in the time i add the data..
I suspect that you are calling the Fillcombo() method in Form_Load event handler.
if you want to update the combobox for every insert and delete operations in your table you need to call Fillcombo() immediatly after executing the command.
Try This:
int status = dataCommand.ExecuteNonQuery();
transakcija.Commit();
if(status > 0)
{
Fillcombo();
MessageBox.Show("You added a new movie!");
}
in your FillCombo clear the items before adding the new items to remove the duplicates.
comboBox1.Items.Clear(); //add this statetement before adding items
comboBox2.Items.Clear(); //add this statetement before adding items
while (myReader.Read())
{
string sName = myReader.GetString("film");
comboBox1.Items.Add(sName);
comboBox2.Items.Add(sName);
}
ADO.NET object works in a disconnected state, so, adding a record to your datatable doesn't automatically shows up in your combo. You need to call again FillCombo, (clearing the items already in combos, going again to the database to retrieve every record again, adding them to your comboboxes) or just simply adding the film to your already filled combos as a single item
Also pay attention to Sql Injection (use always a parameterized query)
private void button5_Click(object sender, EventArgs e)
{
string conString = "datasource=localhost;port=3306;username=root;password=";
string cmdText = "Insert INTO filmi.film (film) VALUES (#film)";
using(MySqlConnection dataConnection = new MySqlConnection(conString))
using(MySqlCommand dataCommand = new MySqlCommand(cmdText, dataConnection))
{
try
{
dataConnection.Open();
dataCommand.Parameters.AddWithValue("#film", this.tB_Dodaj.Text);
// If ExecuteNonQuery returns a value > 0 then your record has been inserted
// Just add the name of the film to the two combos
if(dataCommand.ExecuteNonQuery() > 0)
{
MessageBox.Show("You added a new movie!");
comboBox1.Items.Add(this.tB_Dodaj.Text);
comboBox2.Items.Add(this.tB_Dodaj.Text);
}
}
catch(Exception ex)
{
MessageBox.Show("Fail to add a new movie! " + ex.Message);
}
}
}
As a last note, watch carefully your fillcombo method. You don't close and dispose the connection.

Getting data from MS Access database and display it in a listbox

How do I read data in ms access database and display it in a listbox. I have the codes here but i got errors.
private void button3_Click(object sender, EventArgs e)
{
using (OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\Sisc-stronghold\mis!\wilbert.beltran\DataBase\DataStructure.accdb"))
using(OleDbCommand cmd = new OleDbCommand(" SELECT * from TableAcct", conn))
{
conn.Open();
OleDbDataReader Reader = cmd.ExecuteReader();
//if (Reader.HasRows)
if (Reader.HasRows)
{
Reader.Read();
listBox1.Text = Reader.GetString("FirstName");
}
}
the errors are here:
1. Error 1 The best overloaded method match for'System.Data.Common.DbDataReader.GetString(int)' has some invalid arguments.
2. Error 2 Argument '1': cannot convert from 'string' to 'int'
try this one,
List<String> firstName = new List<String>();
List<String> lastName = new List<String>();
private void loadButton_Click(object sender, EventArgs e)
{
cn.Open();
OleDbDataReader reader = null;
cmd = new OleDbCommand("select* from Records", cn);
reader = cmd.ExecuteReader();
while (reader.Read())
{
firstName.Add(reader["FirstName"].ToString());
lastName.Add(reader["LastName"].ToString());
}
cn.Close();
}
then in your search button, insert this,
private void searchButton_Click(object sender, EventArgs e)
{
clearSearchResult();
try
{
int totalItems = FirstName.Count;
int count = 0;
while (count < totalItems)
{
if (textBox6.Text == FirstName[count].ToString())
{
listBox1.Items.Add(FirstName[count].ToString());
count = 100;
}
else
{
count++;
}
It's good to use when you want to show the information of the "FirstName" in the listBox1_SelectedIndexChanged if you want. here's an example,
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
int totalItems = lastName.Count;
int count = 0;
while (count < totalItems)
{
if ((listBox1.SelectedItem.ToString()) == firstName[count].ToString()))
{
textBox1.Text = firstName[count].ToString();
textBox2.Text = lastName[count].ToString();
count = 100;
}
else
{
count++;
}
}
hope this helps,
change
listBox1.Text = Reader.GetString("FirstName");
to
listBox1.Text = Reader.GetString(0); // zero base ordinal of column
GetString() takes an int as the parameter and not a string. Meaning that you must use the index of the column.
In your specific circumstance as "FirstName" is the second column the index would be 1:
listBox1.Text = Reader.GetString(1);
http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdatareader.getstring.aspx
Thy using a While loop
while(reader.Read())
{
listbox1.Items.Add(reader["FirstName"]);
}
This moves through all the rows you selected. reader.Read() returns false if there are no more rows.
Also: if you Want to retrive valmue from a column I suggest you do it with the index ón the reader instance. Like my example.
var value = reader["ColumnName"];
This increases readability comparing to
var value = reader.GetString(0);
UPDATE
If you want to only display the fist value - I suggest you use cmd.ExecuteScalar() and the adapt you sql to only return the value you need:
using(OleDbCommand cmd = new OleDbCommand("SELECT firstname from TableAcct", conn))
{
conn.Open();
var firstName = cmd.ExecuteScalar();
}
Be aware the this will give you the first "FirstName" in the table. And since there is no "order by firstname" or "where someKey = 1" - this might not rturn that you expected.
If you want to create MS Access data base and to access it, and to display data in some component, like here i will show you.how to connect with MS Access Data Base and display data from data base in Label.
First of all create any Access data base like here "PirFahimDataBase".
Now in your Visual Studio go to the menu and do this
Click Data
Add New Data Base
Click Next
Click New Connection
Now change the Data Source by clicking Change and select Microsoft Access data base files
Click Browse for selecting your created data base
Now in Button ClickEvent paste these code which will get data from data base and will show it in the label
using System.Windows.Forms; //these two lines should be written before namespace at top of the program
using System.Data.OleDb;
private void button1_Click(object sender, EventArgs e)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data source= C:\Users\pir fahim shah\Documents\PirFahimDataBase.accdb";
try
{
conn.Open();
MessageBox.Show("connected successfuly");
OleDbDataReader reader = null; // This is OleDb Reader
OleDbCommand cmd = new OleDbCommand("select TicketNo from Table1 where Sellprice='6000' ", conn);
reader = cmd.ExecuteReader();
while (reader.Read())
{
label1.Text= reader["TicketNo"].ToString();
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to connect to data source");
}
finally
{
conn.Close();
}
}//end of button click event
Your error is in this line:
listBox1.Text = Reader.GetString("FirstName");
You must pass a number in the GetString() function.
DataColumn[] PrimaryKeyColumn = new DataColumn[1]; //Define Primary coloumn
DataSet dataSet = new DataSet();
DataTable dataTable = new DataTable();
ReadAndUpdateExcel.ReadExcel(strPath, sheetName, out dataSet);
dataSet.Tables.Add(dataTable);
PrimaryKeyColumn[0] = dataSet.Tables[0].Columns[0];
dataSet.Tables[0].PrimaryKey = PrimaryKeyColumn;
string num = dataSet.Tables[0].Rows[dataSet.Tables[0].Rows.IndexOf(dataSet.Tables[0].Rows.Find(strTCName))]["ACNO"].ToString();
//string country

Returning string from a dropDownlist control

I have what is a very elementary problem I realize, I am trying to return a string value from a selected value of a DropDownList upon selected index change but for some or other reason it is not happening.
protected void drpMinisters_SelectedIndexChanged(object sender, EventArgs e)
{
name = drpMinisters.SelectedValue;
LabMessage.Text = name;
}
When I try to add name to a database I get a NullReferenceException.
protected void butSubmitMinister_Click(object sender, EventArgs e)
{
int index = drpMinisters.SelectedIndex;
if (index == 0)
{
LabMessage.Text = "Please select a minister";
return;
}
try
{
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = #"INSERT INTO MinisterTable(MinisterName)VALUES(" + name + "')";
cmd.ExecuteNonQuery();
LabMessage.Text = "The record was successfully added";
conn.Close();
}
catch (Exception ex)
{
LabMessage.Text = ex.ToString();
}
}
Advice perhaps.
I assume that you get the NullRefernceException on your connection object conn on this line:
OleDbCommand cmd = conn.CreateCommand();
Remember that all objects (also your name variable) are disposed at the end of the current page-lifecycle. You can use the control's ViewState to maintain values across postbacks, f.e. the SelectedValue property of your DropDownList.
You should also create the connection where you use it and always dispose it as soon as you're finished, best by using the using-statement. Otherwise other threads(requests) would need to create a new physical connection whenever this is still open:
string sql = "INSERT INTO MinisterTable(MinisterName) VALUES(#MinisterName);";
using(var con = new OleDbConnection(connectionString))
using(var cmd = new OleDbCommand(sql, con))
{
cmd.Parameters.AddWithValue("#MinisterName", drpMinisters.SelectedValue);
con.Open();
cmd.ExecuteNonQuery();
}
well i dont think your problem is with the database part, it actually lies in how you are getting the selected value from your dropdown list. if you want to get the string value that actually appears in the dropdown list, then you should use the following .
string name= (string)drpMinisters.SelectedItem;
in case you want the text in the text area of combobox then use SelectedText property

Categories