ComboBox doesn't show the data - c#

ComboBox doesn't show the data, I populate my combobox with data from my database this way:
private void PartDefective(string id)
{
cmd = new SQLiteCommand("Select * FROM Part_defective where testers = '" + id + "'", DBcon);
if (DBcon.State == ConnectionState.Closed)
DBcon.Open();
myDA = new SQLiteDataAdapter(cmd);
myDataSet = new DataSet();
myDA.Fill(myDataSet, "comboBox6");
this.comboBox6.DataSource = myDataSet.Tables["comboBox6"].DefaultView;
this.comboBox6.ValueMember = "Part";
this.comboBox6.DisplayMember = "Part";
this.comboBox6.SelectedItem = "ID";
this.comboBox6.SelectedIndex = -1;
DBcon.Close();
}
And to show the data from the database I used :
private void comboBox6_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.comboBox6.SelectedValue == null)
{
testerid = "1";
}
else
{
part = this.comboBox6.SelectedText.ToString();
}
}

There is absolutely no reason to define the SelectedItem or SelectedIndex.
The SelectedIndexChanged Event is also completely redundant for displaying your combobox.
Remove these lines and see if it solved your problem.
this.comboBox6.SelectedItem = "ID";
this.comboBox6.SelectedIndex = -1;
If the combobox is still empty, the root of problem has to be with the fetching of your data and filling the datasource.

Put a breakpoint on this line:
this.comboBox6.DataSource = myDataSet.Tables["comboBox6"].DefaultView;
And then look at the value of myDataSet.Tables["comboBox6"] in the watch or quickwatch window. Are there any rows?
Also change your code:
string sql = "Select * FROM Part_defective where testers = '" + id + "'";
cmd = new SQLiteCommand(sql, DBcon);
Put a breakpoint there, see what the value of sql is.
Manually run the sql against your database and see if there are any results.

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;
}

Data gets duplicated in datagridview when query applied?

I am trying to perform CRUD operation on winform
This is for ASP.NET winform in which whenever I try to insert, update or delete the data to or from the database first of all rows and inside content gets duplicated
https://imgur.com/a/d5jgv6H
however, upon restarting the application data shows up correctly
private void button2_Click(object sender, EventArgs e)
{
//insert
try
{
con.Open();
//.text property gets/Sets text associated with this control
String name = textBox1.Text.ToString();
String address = textBox2.Text.ToString();
String number = textBox3.Text.ToString();
long pnumber = Int64.Parse(number);
String sem = textBox4.Text.ToString();
long semester = Int64.Parse(sem);
string branch = comboBox1.SelectedItem.ToString();
String query = "insert into student values('" + name + "','" + address + "'," + pnumber + "," + semester + ",'" + branch + "')";
SqlCommand sqlcom = new SqlCommand(query, con);
int i = sqlcom.ExecuteNonQuery();
if (i >= 1)
{
MessageBox.Show("Student has been Registered: " + name);
}
else
{
MessageBox.Show("Registration Failed ! ");
}
//clearing data
button1_Click(sender, e);
show();
con.Close();
}
catch (Exception exp)
{
MessageBox.Show("Error is : " + exp.ToString());
}
}
void show()
{
String query = "select * from student";
SqlDataAdapter adapter = new SqlDataAdapter(query, con);
DataTable dataInTable = new DataTable();
adapter.Fill(dataInTable);
//DataRow represents row of data in DataTable
foreach (DataRow item in dataInTable.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item[0].ToString();
dataGridView1.Rows[n].Cells[1].Value = item[1].ToString();
dataGridView1.Rows[n].Cells[2].Value = item[2].ToString();
dataGridView1.Rows[n].Cells[3].Value = item[3].ToString();
dataGridView1.Rows[n].Cells[4].Value = item[4].ToString();
}
}
The query works fine but rows still get duplicated. What's the problem?
I can't find any bug, so I assume I am doing something incorrectly.
Your show method adds rows to the grid, but it never removes the rows which are already in the grid.
Normally one would use data binding to populate a DataGridView or other data-bound controls. I'm going to assume you have reasons for just adding rows directly (perhaps it's simpler for your needs) and not change that. Given that structure, probably the easiest thing to do is just to clear the grid before adding the new rows:
void show()
{
String query = "select * from student";
SqlDataAdapter adapter = new SqlDataAdapter(query, con);
DataTable dataInTable = new DataTable();
adapter.Fill(dataInTable);
dataGridView1.Rows.Clear(); // <--- here
foreach (DataRow item in dataInTable.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item[0].ToString();
dataGridView1.Rows[n].Cells[1].Value = item[1].ToString();
dataGridView1.Rows[n].Cells[2].Value = item[2].ToString();
dataGridView1.Rows[n].Cells[3].Value = item[3].ToString();
dataGridView1.Rows[n].Cells[4].Value = item[4].ToString();
}
}
That way any time you are about to populate the grid with new data, you first clear the existing data from it.

Show data in Textboxes from database in C#

Is there anything wrong with my code? It is not showing data in textboxes. The same funtion is working for another table in database but not for this one.
private void metroButton1_Click(object sender, EventArgs e)
{
con = new SqlConnection(constr);
String query = "Select FROM Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
cmd = new SqlCommand(query, con);
con.Open();
try
{
using (SqlDataReader read = cmd.ExecuteReader())
{
while (read.Read())
{
// metroTextBox1.Text = (read["ID"].ToString());
metroTextBox2.Text = (read["Name"].ToString());
metroTextBox3.Text = (read["F_Name"].ToString());
metroTextBox4.Text = (read["Std_Age"].ToString());
metroTextBox5.Text = (read["Address"].ToString());
metroTextBox6.Text = (read["Program"].ToString());
metroComboBox1.Text = (read["Course"].ToString());
}
}
}
finally
{
con.Close();
}
}
you need to give column names in the select statement or select *
for example :
String query = "Select * from Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
Not related to Question: you can change the while loop to if condition if you have one record for given id. even there are many records for given id you will see the last record data only because of the while loop will overwrite the textboxes in every record.
Update :
There isn't anything wrong with Syntax because the same syntax is
working for modifying teacher funtion.
No, this is incorrect, remove the try catch in your code then you will see the exception of syntax error

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());
}

Sorting of a filtered GridView

The Problem:
I'd like to allow sorting (ASC/DESC) and filtering on my GridView.
I have managed to implement both via a DropDownList and DataBound fields on my GridView. However, when a user selects a filter from the DropDownList, then attempts to sort the resulting data, the GridView "forgets" the currently selected filter and just sorts all of my data, not the filtered data like you would expect.
What i've tried:
Here is my filtering code...
private void FilterGridView()
{
SqlCommand command = new SqlCommand();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = WebConfigurationManager.ConnectionStrings[1].ConnectionString;
command.CommandText = string.Format("SELECT * FROM Products WHERE {0} = 1", ddlProdFilter.SelectedValue);
if (ddlProdFilter.SelectedValue == "on_sale")
{
command.CommandText = "SELECT * FROM Products INNER JOIN ProductVariants ON [Products].product_id = [ProductVariants].product_id WHERE [ProductVariants].on_sale = 1";
}
else if (ddlProdFilter.SelectedValue == "*")
{
command.CommandText = "SELECT * FROM Products";
}
command.Connection = connection;
SqlDataAdapter sqlAdapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
sqlAdapter.Fill(ds);
if (ds.Tables[0].Rows.Count == 0)
{
pnlNoProducts.Visible = true;
}
else
{
pnlNoProducts.Visible = false;
}
gvAllProducts.DataSource = ds;
}
Where the drop down lists selected value corresponds to a column name in my table.
Here is my sorting code...
private void SortGridView(string sortExpression, string sortDir)
{
SqlCommand command = new SqlCommand();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = WebConfigurationManager.ConnectionStrings[1].ConnectionString;
if (!string.IsNullOrEmpty(sortDir))
{
command.CommandText = "SELECT * FROM Products ORDER BY " + sortExpression + " " + sortDir;
}
command.Connection = connection;
SqlDataAdapter sqlAdapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
sqlAdapter.Fill(ds);
DataTable dt = new DataTable();
dt = ds.Tables[0];
gvAllProducts.DataSource = dt;
}
Where the sortExpression corresponds to a selected DataBound field e.g. product_id, and finally, sortDir is a session variable used accurately keep track of the sort order between postbacks.
Event handlers.
protected void gvAllProducts_OnSorting(object sender, GridViewSortEventArgs e)
{
if (e.SortDirection == SortDirection.Ascending && SessionHelper.GetSessionStringValue("SORT_DIRECTION") != "DESC")//if ascending and the last sort order wasn't descending, sort by DSC
{
SessionHelper.SetSessionValue("DESC", "SORT_DIRECTION");
}
else if (SessionHelper.GetSessionStringValue("SORT_DIRECTION") == "DESC")//otherwise, if the last sort order was desc, sort asc
{
SessionHelper.SetSessionValue("ASC", "SORT_DIRECTION");
}
SortGridView(e.SortExpression, SessionHelper.GetSessionStringValue("SORT_DIRECTION"));
BindDataSource();
e.Cancel = true;
}
protected void ddlProdFilter_SelectedIndexChanged(object sender, EventArgs e)
{
FilterGridView();
BindDataSource();
}
protected void gvAllProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvAllProducts.PageIndex = e.NewPageIndex;
FilterGridView();
BindDataSource();
}
I've tried calling the filtering code when/after i do my sorting which would make sense, but the same things occurs. I've been googling for about 2 hours and can't find a solution to this.
Has anyone come up against this issue before? Could you offer a potential solution or some guidance here?
Thankyou
Your query in SortGridView(..) method doesn't take into account the ddl values. You should call your FilterGridView(..) method OnSorting event, or similar (call it BindGrid() for example)
Managed to get it working by including the ddl value in my sort queries:
private void SortGridView(string sortExpression, string sortDir, string filter)
{
SqlCommand command = new SqlCommand();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = WebConfigurationManager.ConnectionStrings[1].ConnectionString;
if (filter == "*")
{
command.CommandText = "SELECT * FROM Products ORDER BY " + sortExpression + " " + sortDir;
}
else if (filter == "on_sale")
{
command.CommandText = "SELECT * FROM Products INNER JOIN ProductVariants ON [Products].product_id = [ProductVariants].product_id WHERE [ProductVariants].on_sale = 1 ORDER BY [Products]." + sortExpression + " " + sortDir;
}
else
{
command.CommandText = "SELECT * FROM Products WHERE " + filter + " = 1 ORDER BY " + sortExpression + " " + sortDir;
}
command.Connection = connection;
SqlDataAdapter sqlAdapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
sqlAdapter.Fill(ds);
DataTable dt = new DataTable();
dt = ds.Tables[0];
gvAllProducts.DataSource = dt;
}
Instead of having a void method for FilterGridView you should have a "layer" method that retrieves the appropriate data. It should return a properly filled DataSet or Collection object rather than assigning data sources directly. This way, your retrieval method will set up any filtering and/or sorting conditions necessary. Then in your action method you would specify:
gvAllProducts.DataSource = GetFilteredSortedData();
If you need you can build it so that it accepts parameters and use overloads for default "empty" values.

Categories

Resources