I have a comboBox and a checkListBox in my windows form application that connected to my SQL database. I got the binding data part working, but I am not sure how to show the datas in checkListBox when the comboBox item is selected. Let say I have 10 items in my comboBox that bind with my SQL database and they are under the column name ("application name ") such as excel, word, android, eclipse etc.... I call this method when the form begin to load. Sorry for the long code.
Here is my code for that applicationComboBox
private void loadComboBox()
{
myConn = new SqlConnection("Server = localhost; Initial Catalog= dbName; Trusted_Connection = True");
try
{
myConn.Open();
//my table name is Application_Detail
string query = "select * from Application_Detail";
myCommand = new SqlCommand(query, myConn);
//reading the value from the query
SqlDataReader dr = myCommand.ExecuteReader();
//Reading all the value one by one
while (dr.Read())
{
//column is 1 in Application_Detail Data
//GetString(1) display the 2nd column of the table
string name = dr.GetString(1);
//display the application name in column 2 -
applicationComboBox.Items.Add(name);
}
myConn.Close();
}catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The outcome of this part of code is:
//label Name //Application Name
Application Name:
Excel
Word
NotePad
PowerPoint
SubLime
Eclipse
After I call this method, I want to display the teacher name that is according to what the user selected in this applicationComboBox. So if teacher 1,2,3 is using Excel and the user selected excel from the comboBox, the checkListBox will display teacher 1,2,3 and vice versa. To do this, I call the method at the comboBox1_SelectedIndexChanged method because I want to display the detail when I select an item from the comboBox. Below is my code
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
//I check if the comboBox index is at 0, it disable the button.
if (applicationComboBox.SelectedIndex == 0)
{
exportButton.Enabled = false;
this.teacherCheckListBox.DataSource = null;
teacherCheckListBox.Items.Clear();
}
//it it is not at 0,
else
{
exportButton.Enabled = true;
//call this method
fill_checkListBox();
}
//teacherCheckListBox
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void fill_checkListBox()
{
myConn = new SqlConnection("Server = localhost; Initial Catalog= dbName; Trusted_Connection = True");
try
{
myConn.Open();
//for reading purpose, I break down by long statement
//In this statement, I left join 3 table (Teacher_Detail, AppUser_Detail, and Application_Detail table). My AppUser_Detail contains all 3 id (teacherId, applicationId, and AppUserId). I then set filter the table using `where` keyWord to make the applicationId = the comboBox text
string query = "SELECT
td.chineseName,
ad.applicationId,
aud.applicationId,
ad.applicationName
FROM[AppUser_Detail] as aud
LEFT JOIN[Teacher_Detail] as td
ON aud.teacherId = td.teacherId
LEFT JOIN[Application_Detail] as ad
ON aud.applicationId = ad.applicationId
where aud.applicationId = '" + applicationComboBox.Text + "' AND NOT(td.teacherId IS NULL)
";
myCommand = new SqlCommand(query, myConn);
//reading the value from the query
SqlDataReader dr = myCommand.ExecuteReader();
//Reading all the value one by one
while (dr.Read())
{
//column is 0 where the teacherName belong in my Teacher_Detail table
string name = dr.GetString(0);
//I tried to set the text of the checkListBox as the teacherName, but I can't somehow
teacherCheckListBox.Text = name;
}
myConn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
When I run the program like this, it said Conversion failed when converting the varchar value "Excel" to data type int. Is there a way to fix it? it shouldn't be a problem because in my Application_Detail table, my applicationName's and my teacherName's data type is set as nvarchar(50) and applicationId and teacherId = int;
The problem is with this line, I would think:
where aud.applicationId = '" + applicationComboBox.Text +
Based on your code, I would think that applicationId is an int and applicationComboBox.Text is just that, text.
Try this:
where ad.applicationName = '" + applicationComboBox.Text.Trim() +
Try this:
if (string.IsNullOrWhiteSpace(teacherCheckListBox.FindString(name))
{
teacherCheckListBox.Items.Add(name);
}
Related
I have an Access database that has name ID-s in a column and I filled up the first column with those ID-s (38, 51, 88) and what I want to do is based on those ID-s I want to fill up the last selected column with some other data that are in the Access database but in another table.
For example, ID 38 would give me a price or a name in that row.
I tried it a lot of times but couldn't find a solution and I don't know If I have to use SQL for this or something else.
I got the needed SQL code but I don't know how to use it for the datagridview.
I have used something like that to fill up combo boxes like this:
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = "the connection string";
connection.Open();
string query2 = "SELECT Name From Names";
command.CommandText = query2;
OleDbDataReader reader2 = command.ExecuteReader();
while (reader2.Read())
{
Combobox1.Items.Add(reader2["Name"].ToString());
}
connection.Close();
And now I think I should make an if statement where it checks if the 38 ID is in the DataGridView, then fill the other cell with the value in the same row of the Access table.
Do you want to populate the datagridview with the corresponding Price and Name that from another table?
Here is a demo you can refer to.
private void btnSetPriceName_Click(object sender, EventArgs e)
{
string constr = #"connection string";
// create sql string
StringBuilder strSQL = new StringBuilder();
strSQL.Append("select Price, Name from PriceName where ");
for(int i = 0;i< dataGridView1.Rows.Count - 1;i++)
{
// get Id from string, like "38/1/R"
string Id = dataGridView1.Rows[i].Cells[0].Value.ToString().Split('/')[0];
if (i == 0)
strSQL.Append("Id = " + Id);
else
strSQL.Append("or Id = " + Id);
}
using (OleDbConnection conn = new OleDbConnection(constr))
{
OleDbCommand cmd = new OleDbCommand (strSQL.ToString(), conn);
conn.Open();
try
{
OleDbDataReader reader = cmd.ExecuteReader();
if (reader != null && reader.HasRows)
{
int rowindex = 0;
while (reader.Read())
{
// Set Price/Name column value
dataGridView1.Rows[rowindex].Cells["Price"].Value = reader[0].ToString().Trim();
dataGridView1.Rows[rowindex].Cells["Name"].Value = reader[1].ToString().Trim();
rowindex++;
}
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine("\nError:\n{0}", ex.Message);
}
}
}
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);
}
I'm struggling to change a variable from a database into a usable Int so I can compare against the database to delete rows.
Here's the code I'm using:
private void EditEmployee_Load(object sender, EventArgs e)
{
DataTable table = new DataTable(); //creates a Table to store the data before populating the ComboBox
string connstring = #"Provider = Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\HoliPlanData.accdb;Persist Security Info=False";
try
{
using (OleDbConnection conn = new OleDbConnection(connstring))
{
conn.Open();
string query = "SELECT PayrollNo, (FirstName + ' ' + LastName) AS NAME FROM [Employee]";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
adapter.Fill(table);
DropBoxEmp.DataSource = table;
DropBoxEmp.DisplayMember = "NAME";
DropBoxEmp.ValueMember = "PayrollNo";
string BadNumber = DropBoxEmp.ValueMember;
int GoodNumber = Int32.Parse(BadNumber);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
The problem is that the string BadNumber is set to the string "PayrollNo", instead of a string version of the Int that the Datatable stores PayrollNo as. When I set the DisplayMember to "PayrollNo", the combobox displays 1 and 2 and so on, as the Int's selected in the SELECT query.
Why does BadNumber take the literal assigned to DropBoxEmp.ValueMember instead of the numbers? Any help would be gratefully received.
You want DropBoxEmp.SelectedItem, not ValueMember. You are misunderstanding what the ValueMember property is. It tells the combo box which field in its binding to use as the backing value.
To unbox, do this:
var theItem = DropBoxEmp.SelectedItem as DataRowView;
MessageBox.Show(theItem[0].ToString());
-- as an aside, the data adapter will open the connection so you don't need to do that.
Try using the column name and the row index to get the value:
if(table.Rows.Count==1) // if it's supposed to be unique
{
int GoodNumber = Int32.Parse(table.Rows[0]["PayrollNo"].ToString());
}
else
{
//Show some error
}
I'm relatively new but I've been researching this issue for over 2 days, so I think I've done my due diligence ... however if this has already been answered before I apologize.
My basic issue is I'm trying to create some dependent combo boxes. The wrinkle is the displayed value is typically not the lookup value for the next query/Combo box (I'm using an OLEDB compliant data base)
For example: Table1 (T1) contains ID (int) & NM (string), Table2 (T2) contains ID (int) & STATUS (string). I run Query1 (Q1) to display T1.NM in Combobox1 (CB1), when selected I run Query1a to lookup/get the selected Table1.ID to pass to Query2 that populates Combobox2. The connection string and Q1 work fine, CB1 displays properly, but once I select this error is thrown:
"OleDbException .. SQL Passthru expression ... using equals (=) has components that are of different data types"
// ** Initial connection & populate CB1 - This works fine **
public void comboboxLoad()
{
string conn3str = <Connection String >;
string query1 = "select NM from Table1 where REFVALUE=1 ; ";
OleDbConnection conn3 = new OleDbConnection(conn3str);
OleDbCommand tblRow1 = new OleDbCommand(query1, conn3);
OleDbDataReader rdRow1;
try
{
conn3.Open();
lblConnState.Text = "Connection Successful";
rdRow1 = tblRow1.ExecuteReader();
while (rdRow1.Read())
{
int colindx1 = rdRow1.GetOrdinal("NM");
string sItbl = rdRow1.GetString(colindx1);
CB1.Items.Add(sItbl);
}
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
}
// ** Get value from CB1, create query to populate CB2 **
private void CB1_SelectedIndexChanged(object sender, EventArgs e)
{
string conn3str = <Connection String >;
OleDbConnection conn3 = new OleDbConnection(conn3str);
conn3.Open();
// Pass the selected value from CB1 (string) equal to Table1.NM (string)
string query1a = "select ID from Table1 where NM = '" + CB1.Text + "' ; ";
OleDbCommand TabID = new OleDbCommand(query1a, conn3);
int TabId2 = Convert.ToInt32(TabID.ExecuteScalar());
// Pass the variable TabId2 (int) equal to Table2.ID (int)
string query2 = "select STATUS from Table2 where ID = '" + TabId2 + "'; ";
OleDbCommand tblRow2 = new OleDbCommand(query2, conn3);
// OleDbDataReader rdTabID;
// OleDbDataReader rdRow2;
try
{
OleDbDataReader rdRow2 = TabID.ExecuteReader();
OleDbDataReader rdTabID = tblRow2.ExecuteReader(); // ** Error points to this line **
while (rdRow2.Read())
{
int TabIdidx = rdTabID.GetOrdinal("ID");
string TabIDVal = rdTabID.GetString(TabIdidx);
// Pass reference ID to label on form
lblBTableID.Text = TabId2.ToString();
int colindx1 = rdRow2.GetOrdinal("STATUS");
string sIntVal = rdRow2.GetString(colindx1);
cmbLowLvl.Items.Add(sIntVal);
}
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
}
Are you positive you're getting a value back on this line int TabId2 = Convert.ToInt32(TabID.ExecuteScalar());?
Convert.ToInt32 doesn't throw a ArgumentNullException like int.Parse does so it's possible that the variable is not getting set.
Also you may want to consider changing your queries to use parameterized SQL rather than concatenation for security purposes.
https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters(v=vs.110).aspx
I've been able to figure out the problem. I'm really not sure why it didn't work originally, but I think it was a reader mismatch, since I was only looking for a single value back from the query ExecuteScalar() seemed to do the trick and I didn't need the 'while' loop. The working code is below.
Next I'll need to pass this return value (ID) in my next query to populate CB2. Thanks #
private void CB1_SelectedIndexChanged(object sender, EventArgs e)
{
string conn3str = <Connection String >;
OleDbConnection conn3 = new OleDbConnection(conn3str);
// Pass the selected value from CB1 (string) equal to Table1.NM (string) but return the int ID.
OleDbCommand tblRow2 = new OleDbCommand("select ID from Table1 where NM= '"+ CB1.Text +"' ;" , conn3);
try
{
conn3.Open();
string r2 = Convert.ToString(tblRow2.ExecuteScalar());
MessageBox.Show(r2);
lblBTableID.Text = "ID Code= " + r2;
conn3.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
}
I have a windows form application. Inside the form, I have a ComboBox and a list box. When I select the comboBox, I want to display a list of item that the user can check in the checkListBox, I figured out how to bind data to comboBox part but I am not sure how to display a list of values so that the user can select in the checkListBox. Let say I have a list of items that stored in a SQL database call item_table, how can I display it to the checkListBox according to when I select from the comboBox? Code for reference will be appreciated. Thanks
For example,
let say the user select "Amy" from the comboBox, the checkListBox will display a list of item "item 1, item2, item3, item4".
when the user select "Brad" from the comboBox, it will display a list of item: "item2, item5, item10
etc
Here is my database table in (SQL) server
user_Detail
In my user_Detail table , I have 10 user and each of them have a primary key (userId) and a column (userName);
item_Detail
In my item_Detail table, I have 20 items and they also have a primary key (itemId) and a column (itemName)
In the sql console, I inner join the two table (which I am not sure if I need to do the same in my SqlCommand in the code )
Here is my sql command in the console.
select
user_Detail.userId,
user_Detail.userName,
item_Detail.itemId,
item_Detail.itemName
from
item_Detail
INNER JOIN user_Detail ON user_Detail.userId = item_Detail.itemId
Here is my code
namespace Test {
public partial class MainForm: Form {
SqlConnection myConn;
SqlCommand myCommand;
SqlDataReader myReader;
SqlDataAdapter myDa;
DataTable dt;
DataSet ds = new DataSet();
public MainForm() {
InitializeComponent();
// loadComboBox
loadComboBox();
}
//Connect to my db to fetch the data when the application load
private void loadComboBox() {
myConn = new SqlConnection("Server = localhost; Initial Catalog= dbName; Trusted_Connection = True");
string query = "Select * from user_Detail";
myCommand = new SqlCommand(query, myConn);
try {
myConn.Open();
myReader = myCommand.ExecuteReader();
string s = "<------------- Select an item ----------->";
itemComboBox.Items.Add(s);
itemComboBox.Text = s;
while (myReader.Read()) {
//declare a string
object userId = myReader[userId"];
object userName = myReader["userName"];
//my comboBox named userComboBox
userComboBox.Items.Add(userName.ToString());
}
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
//Display some items here (this is my checkListBox
private item_checkListBox(Object sender, EventArgs e){
}
private void load_item(){
}
I wish this could help you.
First, i just want to fix your loadComboBox() because reading it might lead to confusion.
private void loadComboBox() {
myConn = new SqlConnection("Server = localhost; Initial Catalog=dbName; Trusted_Connection = True");
string query = "Select * from user_Detail";
myCommand = new SqlCommand(query, myConn);
try {
myConn.Open();
myReader = myCommand.ExecuteReader();
string s = "<------------- Select an item ----------->";
itemComboBox.Items.Add(s);
itemComboBox.Text = s;
while (myReader.Read()) {
//declare a string
string userId = myReader["userId"].toString();
string userName = myReader["userName"].toString();
//my comboBox named userComboBox
userComboBox.Items.Add(userName);
}
myConn.Close();
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
Make sure to close sql connections after using it. Just open it again if youre going to use it.
Now, you added the userName of your users on your combobox.
Next lets create an event that will be fired whenever you choose from your combobox.
userComboBox.SelectedIndexChanged += (o,ev) => { ChangeCheckListItems(); };
The code above can be read as "if userComboBox changed selected index, call ChangeCheckListItems() method." Whenever you change selection, we will call the said method. You can put that code on your class constructor.
Now what does ChangeCheckListItems() method must contain.
private void ChangeCheckListItems(){
myCheckListBox.Items.Clear();
string selectedText = userComboBox.Text;
switch(selectedText){
case "Amy":
AddItemsForAmy();
break;
case "Brad":
AddItemsForBrad();
break:
}
}
So first, we make sure we clear the myCheckListBox before adding the items to avoid duplication since this method trigger every selection change.
Next we get the selected text from the userComboBox.
Then we will use a switch to choose what we will do depends on the selected userComboBox.
AddItemsForAmy() and AddItemsForBrad() are only example methods.
For example:
private void AddItemsForAmy(){
myConn = new SqlConnection("Server = localhost; Initial Catalog=dbName Trusted_Connection=true;"
string query = "Select * from item_Detail where itemId % 2 = 0"
myCommand = new SqlCommand(query, myConn);
try{
myConn.Open();
myReader = myCommand.ExecuteReader();
while(myReader.Read()){
string itemName = myReader["itemName"].toString();
myCheckListBox.Items.Add(itemName);
}
myConn.Close();
}
catch(SqlExcetion ex){
MessageBox.Show(ex.Message);
}
}
So in my example above, I selected all items with itemId that are even numbers.
And then on while() part, I added those items to the checklistbox.
Its your choice on what items are you going to display for Amy,Brad and other possible users on you database. You can also use parameterized method for shorter solution. Hope this helps. Sorry if its so long.