C# Search Using ComboBox and TextBox (Access Database) - c#

(First of all...... Sorry to my english :D)
I already post my problem here c# Search using ComboBox and Textbox .. no one solved my problem but I used their codes to simplify my codes.
When I started the program the DataGridView looks so normal.. I choose a field in ComboBox and type in TextBox.. the results showed but the problem is.... their's another column that added to the DataGridView and it's empty... I want you to help me to remove that column
Here's the image (I am new here in stackoverflow.. I dont have enough reputation to post images)
public void searchData()
{
string sql = "Select ID,Quantity,Unit,ItemCode,ItemName,Cbm,TotalCbm from Inventory Order By ID asc;";
cmd = new OleDbCommand(sql, con);
try
{
con.Open();
string value = cboFields.Text;
cmd.CommandText = String.Format(
#"Select ID,
Quantity,Unit,ItemCode,ItemName,Cbm,TotalCbm
from Inventory
where {0} like #searchKey Order By ID asc;", value);
cmd.Parameters.AddWithValue("#searchKey", txtSearch.Text.ToString() + "%");
OleDbDataAdapter adp= new OleDbDataAdapter(cmd);
//DataSet ds = new DataSet();
//adp.Fill(ds);
//DGVinventory.DataSource = ds;
DataTable dt = new DataTable();
adp.Fill(dt);
DGVinventory.DataSource = dt;
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
con.Close();
}
}
private void txtSearch_TextChanged(object sender, EventArgs e)
{
searchData();
}

Related

Eliminating an option from a ComboBox (2), based on the input of the first ComboBox (1) c#

I am creating an airline booking system and I have 2 combo boxes. The first is for Departure City and the second is for Arrival City. I want to be able to eliminate the choice in the first combo box from the second, as I don't want the same city to be able to be submitted as both the departure and arrival city. I am querying the city names from a database.
Here is my code:
public partial class main : Form
{
public main()
{
InitializeComponent();
string connectionString = #"Base Schema Name=cyanair;data source=C:\Users\Client 0819\source\repos\Cyanair\cyanair.db";
//Departure ComboBox
SQLiteConnection conn = new SQLiteConnection(connectionString);
try
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "SELECT * FROM CyanairAirports";
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
comboDeparture.DataSource = dt;
comboDeparture.ValueMember = "Descriptions";
comboDeparture.DisplayMember = "Descriptions";
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Arrival ComboBox
private void comboDeparture_DisplayMemberChanged(object sender, EventArgs e)
{
string connectionString = #"Base Schema Name=cyanair;data source=C:\Users\Client 0819\source\repos\Cyanair\cyanair.db";
SQLiteConnection conn = new SQLiteConnection(connectionString);
**String city = comboDeparture.DisplayMember;**
try
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue.ToString() + "'";
richTextBox1.Text = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue + "'";
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
comboArrival.DataSource = dt;
comboArrival.ValueMember = "Descriptions";
comboArrival.DisplayMember = "Descriptions";
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Thanks :)
It looks like you're handling the DisplayMemberChanged event on comboDeparture, and trying to update the values of comboArrival in that handler. However, DisplayMemberChanged only triggers when the DisplayMember property changes.
DisplayMember only tells the control which property to display on a data bound control. It isn't tied to the index or value selected in the ComboBox. So, the only time the code to populate comboArrival runs is in the constructor when you set comboDepartarture.DisplayMember. Instead, handle either ComboBox.SelectedIndexChanged or ComboBox.SelectedValueChanged and set the items of comboArrival.
A few other important things to note about your code.
First, you should use a parameterized query when running Sql Statements, rather than concatenating strings. Concatenating strings as you're doing opens you up to SQL Injection Attacks. I'm not familiar with SqlLite and can't provide you with an example of how to modify your code, but perhaps this question can help.
Second, you don't need to re-run the query every time you change the selected value in comboDeparture. Just add comboArrival's data source as a field on the Form and you can filter it. For example...
public partial class main : Form
{
// Your constructors...
private void comboDepartures_SelectedIndexChanged(object sender, EventArgs e)
{
if (_arrivalsDataSource == null)
{
_arrivalsDataSource = new System.Data.DataTable();
// Load _arrivalsDataSource from the database, basically how you're doing it now.
comboArrival.DataSource = _arrivalsDataSource.DefaultView;
comboArrival.DisplayMember = "Descriptions"
comboArribal.ValueMember = "Descriptions"
}
if (comboDeparture.SelectedIndex == -1)
{
_arrivalsDataSource.DefaultView.RowFilter = null; // Clear the filter.
}
else
{
// Set the filter.
_arrivalsDataSource.DefaultView.RowFilter = $"Description <> '{comboDeparture.SelectedValue}'";
}
}
private System.Data.DataTable _arrivalsDataSource = null;
}

Maintaining state of checkboxes while filtering record using textbox

I am working on a C# windows application to populate records from SQL Server to data grid view, with dynamic checkbox facility in each row. I want to select selected rows for some purpose via checkbox of that particular row. Till now I successfully achieve my target, but I'm facing a minor issue regarding saving a checked status.
For example I want to check only those records whose Name = Max. I have a textbox in that textbox I call text change event with like Query:
try
{
SqlCommand cmd = null;
SqlConnection con = null; Ranks rank = new Ranks();
con = new SqlConnection(cs.DBcon);
con.Open();
cmd = con.CreateCommand();
cmd.CommandText = "Select * from Records where Name like #Name order by Pno";
cmd.Parameters.AddWithValue("#Name", "%" + FilterByNameTextbox.Text.Trim() + "%");
SqlDataAdapter adapter1 = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter1.Fill(dt);
dataGridView1.DataSource = dt;
Make_fields_Colorful();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
If I write Max in filter by name textbox it would return 3 records with name starts with max using like query as I mention code above. So I only check 2 records out of 3 using dynamic checkbox, till now my code runs perfectly. Now I want to check records which name starts from Ali, now when I write ali in my filter by name textbox it will return rows where name like ali , but problem comes here it will remove my previous checked records, so how I would able to save checked records for both max and ali's rows:
Code for adding dynamic checkboxes in each row
DataGridViewCheckBoxColumn checkBoxColumn = new DataGridViewCheckBoxColumn();
checkBoxColumn.Name = "checkBoxColumn";
checkBoxColumn.DataPropertyName = "Report";
checkBoxColumn.HeaderText = "Report";
dataGridView1.Columns.Insert(10, checkBoxColumn);
dataGridView1.RowTemplate.Height = 100;
dataGridView1.Columns[10].Width = 50;
Images:
Image 1
Image 2
I suggest you achieve this by caching selected rows, first you should have a list of cached rows:
List<DataGridViewRow> CachedRows = new List<DataGridViewRow>();
then add event handler on cell value change like the following:
dataGridView1.CellValueChanged += view_CellValueChanged;
and the handler should check if the column changed is the checkbox and checked, should be something like the following:
try
{
if(e.ColumnIndex == indexOfCheckBoxColumn)
{
if((bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == true)
{
CachedRows.Add((DataGridViewRow)dataGridView1.Rows[e.RowIndex].Clone());
}
else if (CachedRows.Contains(dataGridView1.Rows[e.RowIndex]))//Validate if this works, if not you should associate each row with unique key like for example (id) using a dictionary
{
CachedRows.Remove(dataGridView1.Rows[e.RowIndex]);
}
}
}
catch(Exception ex)
{
}
then after the filter changes, re-add the cached rows again, so code becomes:
try
{
SqlCommand cmd = null;
SqlConnection con = null; Ranks rank = new Ranks();
con = new SqlConnection(cs.DBcon);
con.Open();
cmd = con.CreateCommand();
cmd.CommandText = "Select * from Records where Name like #Name order by Pno";
cmd.Parameters.AddWithValue("#Name", "%" + FilterByNameTextbox.Text.Trim() + "%");
SqlDataAdapter adapter1 = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter1.Fill(dt);
dataGridView1.DataSource = dt;
//add folowing
if (CachedRows.Any())
{
dataGridView1.Rows.AddRange(CachedRows.ToArray());
CachedRows.Clear();
}
Make_fields_Colorful();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}

Error : Update requires a valid UpdateCommand when passed DataRow collection with modified rows

I am using Paging to show data in datagridview, but when i try to Update any data with updatebutton data should be updated In datagridview as well as in database.
But I get this error:
Update requires a valid UpdateCommand when passed DataRow collection
with modified rows
which happens on this line:
adp1.Update(dt);//here I am getting error
Below is the code
public partial class EditMediClgList : Form
{
public EditMediClgList()
{
InitializeComponent();
try
{
con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb");
con.Open();
}
catch (Exception err)
{
MessageBox.Show("Error:" +err);
}
cmd1 = new OleDbCommand("Select * from MedicalColeges order by MedicalClgID", con);
ds = new DataSet();
adp1 = new OleDbDataAdapter(cmd1);
adp1.Fill(ds, "MedicalColeges");
dataGridView1.DataSource = ds;
// Get total count of the pages;
this.CalculateTotalPages();
// Load the first page of data;
this.dataGridView1.DataSource = GetCurrentRecords(1, con);
}
private void CalculateTotalPages()
{
int rowCount = ds.Tables["MedicalColeges"].Rows.Count;
this.TotalPage = rowCount / PageSize;
if (rowCount % PageSize > 0) // if remainder is more than zero
{
this.TotalPage += 1;
}
}
private DataTable GetCurrentRecords(int page, OleDbConnection con)
{
dt = new DataTable();
if (page == 1)
{
cmd2 = new OleDbCommand("Select TOP " + PageSize + " * from MedicalColeges ORDER BY MedicalClgID", con);
// CurrentPageIndex++;
}
else
{
int PreviouspageLimit = (page - 1) * PageSize;
cmd2 = new OleDbCommand("Select TOP " + PageSize +
" * from MedicalColeges " +
"WHERE MedicalClgID NOT IN " +
"(Select TOP " + PreviouspageLimit + " MedicalClgID from MedicalColeges ORDER BY MedicalClgID) ", con); // +
//"order by customerid", con);
}
try
{
// con.Open();
this.adp1.SelectCommand = cmd2;
this.adp1.Fill(dt);
txtPaging.Text = string.Format("page{0} of {1} pages", this.CurrentPageIndex, this.TotalPage);
}
finally
{
// con.Close();
}
return dt;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
adp1.Update(dt);//here I am getting error
}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}
}
}
You have Created the OleDbDataAdapter with a Select command only:
adp1 = new OleDbDataAdapter(cmd1);
OleDbDataAdapter requires valid Update, Insert, Delete commands to be used to save the data like this:
adp1.Update(dt);//here I am getting error
You just need to use a OleDbCommandBuilder that will generate the commands for you:
adp1 = new OleDbDataAdapter();
adp1.SelectCommand = cmd1; // cmd1 is your SELECT command
OleDbCommandBuilder cb = new OleDbCommandBuilder(adp1);
EDIT
Since you change the Select command of the OleDbDataAdapter at runtime for paging, what your need is to initialize each time you save data:
private void button1_Click(object sender, EventArgs e)
{
try
{
adp1.SelectCommand = cmd1; // cmd1 is your SELECT command
OleDbCommandBuilder cb = new OleDbCommandBuilder(adp1);
adp1.Update(dt); //here I hope you won't get error :-)
}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}
}
It could be that you are missing Primary Key in the table. You need to make sure primary key is set on a column in your data base table.
I had to alter my (incrementing) index column to the primary key of my table (as Eaint suggest). After this, I had to pull up the DataSet.xsd in designer view, right click on the visual DataTable object and select configure. When the TableAdapter Configuration Wizard opened, I clicked the Advanced Options button. I checked the Generate Insert, Update and Delete statements checkbox then OK and Finish. After this (still in designer view), I selected the visual TableAdapter object which gave me all the full properties. The SQL was autogenerated. Took a while for me to track this down, so I hope it helps someone.
Thanks to "#Chris" the code above works for me.
I needed to specify the Database Table name that will be updated when I Update.
You can read more about that here:
DataAdapter: Update unable to find TableMapping['Table'] or DataTable 'Table'
// This Adapter and Dataset are used for Populating my datagridview,
// so I use them also when I need to Update the Datagridview
SqlDataAdapter kundeTlfAdapter;
DataSet kundeTlfDataSet;
try
{
SqlConnection connection = new SqlConnection("Data source=BG-1-PC\\SQLEXPRESS; Database = Advokathuset; User Id = abc; Password = abc;");
SqlCommand cmd1 = new SqlCommand("Select* From Kunde_Tlf", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(kundeTlfAdapter);
kundeTlfAdapter.SelectCommand = cmd1; // cmd1 is your SELECT command
kundeTlfAdapter.Update(kundeTlfDataSet, "Kunde_Tlf"); //I get eror here if I dont add the name of the table that needs Update "Kunde_Tlf"
}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}

Populating TextBox based on ComBox, Insert into Database through TextBox

I'm having troubles populating TextBoxes based on a ComboBox, Also insertion code won't work.
What should happen is, By selecting a customer from ComboBox, The details gets displayed on Text Boxes, And i can also add a customer to the ComboBox through the TextBoxes, Also there is a DataGridView displaying related info from another table based on my ComboBox selection but that's not the problem now.
Note:
I switched to Visual Studio 2012 recently, I'm assuming that's not a problem.
ComboBox exception:
An exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll but was not handled in user code.
Save button exception:
Input string was not in a correct format.
About the save button, The CustomerID is an Auto increment number, So i should be able to leave it's TextBox blank but it doesn't work when i do.
Table Structure:
Customers
CustomerID [int] [PK] [AutoNumber]
Name [nvarchar]
Phone1 [int]
Phone2 [int]
Address [nvarchar]
Notes [ntext]
Code:
private void FillCombo()
{
string code = "SELECT CustomerID, Name FROM Customers";
SqlCeDataAdapter da = new SqlCeDataAdapter(code, clsMain.con);
DataSet ds = new DataSet();
da.Fill(ds);
cBox1.DataSource = ds.Tables[0];
cBox1.DisplayMember = "Name";
cBox1.ValueMember = "CustomerID";
}
private void frmMain_Load(object sender, EventArgs e)
{
clsMain.con.Open();
FillCombo();
}
private void cBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string code = "SELECT * FROM Customers WHERE CustomerID='" + cBox1.Text + "'";
SqlCeDataAdapter da = new SqlCeDataAdapter(code, clsMain.con);
SqlCeCommandBuilder cmd = new SqlCeCommandBuilder(da);
DataSet ds = new DataSet();
da.Fill(ds);
if (cBox1.SelectedIndex > 0)
{
txt1.Text = ds.Tables[0].Rows[0]["CustomerID"].ToString();
txt2.Text = ds.Tables[0].Rows[0]["Name"].ToString();
txt3.Text = ds.Tables[0].Rows[0]["Phone1"].ToString();
txt4.Text = ds.Tables[0].Rows[0]["Phone2"].ToString();
txt5.Text = ds.Tables[0].Rows[0]["Address"].ToString();
txt6.Text = ds.Tables[0].Rows[0]["Notes"].ToString();
}
}
private void stripSave_Click(object sender, EventArgs e)
{
string code = "INSERT INTO Customers VALUES (#CustomerID, #Name, #Phone1, #Phone2, #Address, #Notes)";
SqlCeCommand cmd = new SqlCeCommand(code, clsMain.con);
cmd.Parameters.AddWithValue("#CustomerID", (txt1.Text); //Tried Parse and Convert.
cmd.Parameters.AddWithValue("#Name", txt2.Text);
cmd.Parameters.AddWithValue("#Phone1", txt3.Text);
cmd.Parameters.AddWithValue("#Phone2", txt4.Text);
cmd.Parameters.AddWithValue("#Address", txt5.Text);
cmd.Parameters.AddWithValue("#Notes", txt6.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Data stored.");
}
Sorry if it's a long code, But i thought it would be easier to spot the problems this way.
It seems like CustomerID is integral value, So you need to change
cmd.Parameters.AddWithValue("#CustomerID", txt1.Text);
to
cmd.Parameters.AddWithValue("#CustomerID", Int32.Parse(txt1.Text));
as per PhoenixReborn
if CustomerID is an auto increment, why are you trying to save it to the database? Kind of defeats the purpose.
then you need to edit your query to
string code = "INSERT INTO Customers(name, phone1, phone2, address, notes) VALUES (#Name, #Phone1, #Phone2, #Address, #Notes)";
SqlCeCommand cmd = new SqlCeCommand(code, clsMain.con);
cmd.Parameters.AddWithValue("#Name", txt2.Text);
cmd.Parameters.AddWithValue("#Phone1", txt3.Text);
cmd.Parameters.AddWithValue("#Phone2", txt4.Text);
cmd.Parameters.AddWithValue("#Address", txt5.Text);
cmd.Parameters.AddWithValue("#Notes", txt6.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Data stored.");
Try this instead:
private void stripSave_Click(object sender, EventArgs e)
{
int id;
string code;
SqlCeCommand cmd;
/*
If textbox is empty or input is not integer, then take the next id from table.
Otherwise, id is set to input value.
*/
if (txt1.Text == String.Empty || !int.TryParse(txt1.Text, out id))
{
/*
Selects max id + 1
If the table is empty, the result will be null
and coalesce will return 0 for the first id number
*/
code = "SELECT COALESCE((SELECT MAX(CustomerID) + 1 FROM Customers), 0);";
cmd = new SqlCeCommand(code, clsMain.con);
id = (int)cmd.ExecuteScalar();
}
code = "INSERT INTO Customers VALUES (#CustomerID, #Name, #Phone1, #Phone2, #Address, #Notes);";
cmd = new SqlCeCommand(code, clsMain.con);
cmd.Parameters.AddWithValue("#CustomerID", id);
cmd.Parameters.AddWithValue("#Name", txt2.Text);
cmd.Parameters.AddWithValue("#Phone1", txt3.Text);
cmd.Parameters.AddWithValue("#Phone2", txt4.Text);
cmd.Parameters.AddWithValue("#Address", txt5.Text);
cmd.Parameters.AddWithValue("#Notes", txt6.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Data stored.");
}
By the way, an important note about your code: Prefer to connect to database everytime you execute a query and close it afterwards. What I mean is that instead of keeping connection open for all the execution time, use something like this:
try
{
clsMain.con.Open();
cmd.ExecuteNonQuery();
clsMain.con.Close();
}
catch (Exception ex)
{
if (clsMain.con.State != ConnectionState.Closed)
clsMain.con.Close();
MessageBox.Show(ex.Message);
}

Filling a DataTable in C# using MySQL

I'm attempting to fill a DataTable with results pulled from a MySQL database, however the DataTable, although it is initialised, doesn't populate. I wanted to use this DataTable to fill a ListView. Here's what I've got for the setting of the DataTable:
public DataTable SelectCharacters(string loginName)
{
this.Initialise();
string connection = "0.0.0.0";
string query = "SELECT * FROM characters WHERE _SteamName = '" + loginName + "'";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataAdapter returnVal = new MySqlDataAdapter(query,connection);
DataTable dt = new DataTable("CharacterInfo");
returnVal.Fill(dt);
this.CloseConnection();
return dt;
}
else
{
this.CloseConnection();
DataTable dt = new DataTable("CharacterInfo");
return dt;
}
}
And for the filling of the ListView, I've got:
private void button1_Click(object sender, EventArgs e)
{
string searchCriteria = textBox1.Text;
dt = characterDatabase.SelectCharacters(searchCriteria);
MessageBox.Show(dt.ToString());
listView1.View = View.Details;
ListViewItem iItem;
foreach (DataRow row in dt.Rows)
{
iItem = new ListViewItem();
for (int i = 0; i < row.ItemArray.Length; i++)
{
if (i == 0)
iItem.Text = row.ItemArray[i].ToString();
else
iItem.SubItems.Add(row.ItemArray[i].ToString());
}
listView1.Items.Add(iItem);
}
}
Is there something I'm missing? The MessageBox was included so I could see if it has populated, to no luck.
Thanks for any help you can give.
Check your connection string and instead of using
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataAdapter returnVal = new MySqlDataAdapter(query,connection);
DataTable dt = new DataTable("CharacterInfo");
returnVal.Fill(dt);
this.CloseConnection();
return dt;
you can use this one
MySqlCommand cmd = new MySqlCommand(query, connection);
DataTable dt = new DataTable();
dt.load(cmd.ExecuteReader());
return dt;
Well, I ... can't figure out what you have done here so I'll paste you my code with which I'm filling datagridview:
1) Connection should look something like this(if localhost is your server, else, IP adress of server machine):
string connection = #"server=localhost;uid=root;password=*******;database=*******;port=3306;charset=utf8";
2) Query is ok(it will return you something), but you shouldn't build SQL statements like that.. use parameters instead. See SQL injection.
3) Code:
void SelectAllFrom(string query, DataGridView dgv)
{
_dataTable.Clear();
try
{
_conn = new MySqlConnection(connection);
_conn.Open();
_cmd = new MySqlCommand
{
Connection = _conn,
CommandText = query
};
_cmd.ExecuteNonQuery();
_da = new MySqlDataAdapter(_cmd);
_da.Fill(_dataTable);
_cb = new MySqlCommandBuilder(_da);
dgv.DataSource = _dataTable;
dgv.DataMember = _dataTable.TableName;
dgv.AutoResizeColumns();
_conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (_conn != null) _conn.Close();
}
}
So, every time I want to display some content of table in mysql database I call this method, pass query string and datagridview name to that method. and, that is it.
For your sake, compare this example with your and see what can you use from both of it. Maybe, listview is not the best thing for you, just saying ...
hope that this will help you a little bit.
Debug your application and see if your sql statement/ connection string is correct and returns some value, also verify if your application is not throwing any exception.
Your connection string is invalid.
Set it as follows:
connection = "Server=myServer;Database=myDataBase;Uid=myUser;Pwd=myPassword;";
Refer: mysql connection strings
Here the following why the codes would not work.
Connection
The connection of your mySQL is invalid
Query
I guess do you want to search in the table, try this query
string query = "SELECT * FROM characters WHERE _SteamName LIKE '" + loginName + "%'";
notice the LIKE and % this could help to list all the data. for more details String Comparison Functions

Categories

Resources