How to automatically read new data from a ListBox? - c#

I'm trying to get all the data from a column in the database. I found how to read the data from a specific column, but it shows only the first value.
Here's some of my code. Any idea how to read and show the rest data from the column?
public partial class main : Form
{
//Connect database
String connectionstring;
SqlConnection connection;
public main()
{
InitializeComponent();
//Connect database
connectionstring = ConfigurationManager.ConnectionStrings["Internet_Recovery.Properties.Settings.customerConnectionString"].ConnectionString;
Run();
}
private void Run()
{
using (connection = new SqlConnection(connectionstring))
//Select ip values from IP_table
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT Ip FROM IP_table ", connection))
{
DataTable iptable = new DataTable();
//Read ip value and add it in the listbox1
adapter.Fill(iptable);
listBox1.DataSource = iptable;
listBox1.ValueMember = "Ip";
listBox1.DisplayMember = "Id";
String num;
num = listBox1.SelectedValue.ToString();

you can do it like this :
DataSet data = new DataSet();
String num;
using (SqlConnection connection = new SqlConnection(connectionstring))
{
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT Ip FROM IP_table", connection))
{
connection.Open();
adapter.Fill(data);
listBox1.DataSource = data.Tables[0];
listBox1.DisplayMember = "Ip";
}
}
num = listBox1.SelectedValue.ToString();

First, your data doesn't have and Id field which you're trying to bind the DisplayMember to. Change your query to
SELECT Id, Ip FROM IP_table
Also you seem to be swapping the DisplayMember and ValueMember. They should be:
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Ip";
This works and displays all data from the Ip column in the list. It seems that you want to display the data from the other columns too. The ListBox control is not the best for that and you should consider using a GridView control instead. However, sometimes we don't care to display the data in grid format and all we care about is displaying it as a concatenated string in each item (e.g. firstname + " " lastname). If that's your case, you can either concatenate the columns in the query or in the code. Let's say you have the following columns in your table:
Id (e.g. 1)
Ip (e.g. 111.111.111)
Location (e.g. Virginia)
Provider (e.g. AT&T)
And let's assume you want to display them like this 111.111.111 AT&T (Virginia), then you can change your query to:
SELECT Id, Ip + ' ' + Provider + ' (' + Location + ')' AS Description FROM IP_table
And now you can change your binding properties to:
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Description";

Related

Getting specific column data from database in C#

I have created a search function that returns product data in a DataGridView (data is coming from local database), it does work but I need to have control over returned data in my grid view.
Current behavior
It returns all columns of database row in DataGridView
What I want
Returning only 2 or 3 columns of searched item instead of all columns
Create new list of searched items so I can edit those returned data
Logic
Search for product
Get product name and price from database, add custom quantity field make new list and add this item to show in DataGridView
Be able to change quantity field in DataGridView
Code
Here is my search code that returns all columns of product table
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
// Following line will show all columns of founded product and replace it with next search result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selectedItems.DataSource = dt;
}
}
}
PS: Code above finds products based on id or name entered in search field and return all columns of product row.
Idea:
I think I can be able to create my list after finding product but the issue I'm facing is that I'm not sure how to get those specific columns from my dt (table row),
Here is what I've tried and failed (commented)
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
//selectedItems.DataSource = dt; //<-- changed with lines below
List<string> items = new List<string>();
items.Add(dt); // <-- here is the issue (it expect to get string of my table row let say: Price column, but I don't know how to get Price column value from dt)
selectedItems.DataSource = items;
}
}
}
PS: code above is just idea and obviously I am not sure if it is best way to do it or not that's why I'm asking here :)
Any suggestions?
Update
I've created new class and added my data to that class as following
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string Qty { get; set; }
}
Then in my query I added
List<Item> itemList = new List<Item>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Item item = new Item();
item.Id = Convert.ToInt32(dt.Rows[i]["Id"]);
item.Name = dt.Rows[i]["Name"].ToString();
item.Price = dt.Rows[i]["SellPrice"].ToString();
item.Qty = dt.Rows[i]["Qty"].ToString();
itemList.Add(item);
}
selectedItems.DataSource = itemList;
Now it does return data in my selectedItems but when I search for next product instead of adding it to the list it replace it with first product.
According to your sql query you are selecting all columns of the table.
To get the specific columns please change your sql query as such:
SqlCommand cmd = new SqlCommand("select Products.id, Products.name from Products where Id=#Id or Name like #Name", cn);
Thank you.
As per my understanding based on the comments, you are looking for some Linq code.
You only need to convert your result to a list that you could use.
Here is some code that might help you achieve this.
var result = dt.AsEnumerable().Select(x=> new {
Id = x["Id"],
Name = x["Name"],
Quantity = {Your Logic here}
});
selectedItems.DataSource = result;
You can then assign result to your datasource. You did not specify what your datasource is assigned to (selectedItems) so I do not know what type it is. but this should theoretically work. Just remove Quantity = {Your Logic here} from the code and see if it display's after which you could then just add it back and populate what you want Quantity to be
UPDATE
Because selectedItems is a DataGridView it requires a DataTable object to display the data. In which case you can not use an anonymous list as I created you would need something like this.
DataTable dtResult = new DataTable();
dtResult.Columns.Add("Id");
dtResult.Columns.Add("Name");
dtResult.Columns.Add("Quantity");
var result = dt.AsEnumerable().Select(x=> dtResult.Rows.Add(x["Id"],
x["Name"],
{Your Logic for Quantity here}
));
selectedItems.DataSource = result;
If you want to test this solution you can create a console application in c# and do something like where you can see the datasource is correct.
You could refer to the following code to show specific column data from database in winform datagirdview.
private void button1_Click(object sender, EventArgs e)
{
string str = "str";
SqlConnection connection = new SqlConnection(str);
connection.Open();
string sql = "select * from Product where Id=#Id or Name like #Name";
SqlCommand command = new SqlCommand(sql,connection);
command.Parameters.AddWithValue("#Id", textBox1.Text);
command.Parameters.AddWithValue("#Name", string.Format("%{0}%", textBox1.Text));
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable table = new DataTable();
adapter.Fill(table);
var dt = from t in table.AsEnumerable()
select new
{
//Name=t.Field<string>("Name"), //The same way to show other columns data
Price = t.Field<string>("Price")
};
dataGridView1.DataSource = dt.ToList();
}
Result:
Database:

Windows Forms get data from database and display in label

I want to grab data from database and display in labels based on what the user selects in the list view.
I'm going off an example that does this with two list views, but I don't know how to do it when I'm sending data to a label.
This is the list view example I'm using (my label code is below this)
private void PopulateRecipeIngredients()
{
string query = "SELECT a.Name FROM Ingredient a " +
"INNER JOIN RecipeIngredient b ON a.Id = b.IngredientId " +
"WHERE b.RecipeId = #RecipeId";
// # is a parameter
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
// whatever recipe is selected in lstRecipes box, get the id of that and pass into query above
command.Parameters.AddWithValue("#RecipeId", lstRecipes.SelectedValue);
// DataTable holds the data return from query
DataTable ingredientTable = new DataTable();
// SqlDataAdapter object adapter fills the ingredientTable DataTable object with results from query
adapter.Fill(ingredientTable);
// Display value of Name ex. salad
lstIngredients.DisplayMember = "Name";
// Id column is how we reference
lstIngredients.ValueMember = "Id";
// connect list box on form to data in recipeTable
lstIngredients.DataSource = ingredientTable;
}
}
MY CODE:
private void PopulateCourseDetails()
{
string query = "SELECT * FROM Course_Info WHERE Id = #CourseId";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#CourseId", lstCourses.SelectedValue);
DataTable courseTable = new DataTable();
adapter.Fill(courseTable);
lblCourseId.Text = "Course_id";
lblCourseSection.Text = "Course_section";
lblCourseName.Text = "Course_name";
lblCourseDay.Text = "Course_day";
lblCourseStartTime.Text = "Course_start_time";
lblCourseEndTime.Text = "Course_end_time";
lblCourseProfessor.Text = "Course_professor";
lblCourseProfessorEmail.Text = "Course_professor_email";
lstCourses.ValueMember = "Id";
}
}
lblCourseId.Text = (string)courseTable.Rows[0]["Course_id"]
should work as long as you have one row in the result table
Assuming that your DataTable has now been properly populated, you now have a table with a number of rows.
First you need to pull out the first row
var row = courseTable.Rows.FirstOrDefault();
Now you've got a row with a number of columns. You can access each column by either index or column name.
lblCourseId.Text = row[0];
If you want the label to maintain it's header, you can do something like
lblCourseId.Text = "Course_id: " + row[0];

C# Converting String to Int from Access Database and ComboBox

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
}

Why is my drop down list showing old values instead of null?

I have a C# .NET web program which has dropdown lists of manufacturers and models of cars. Whenever you click on a manufacturer it should give you their models. The list for the models is binding fine as long as the manufacturer in question has many models. Once I click a manufacturer that has no models in the models database table, the Models dropdown list still keeps the values for the previous manufacturer instead of binding null and clearing the dropdown list options for the manufacturer with no models.
The function in question is shown below:
public void BindModels(int manufacturer)
{
int numberOfModels;
string strConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString2"].ToString();
SqlConnection conn = new SqlConnection(strConnectionString); // Connect to Carsales database
conn.Open(); // Select all models for a particular make
string com = "SELECT ModelID, ModelName From VehiclesModels Where ManufacturerID = " + manufacturer + " ";
SqlDataAdapter adpt = new SqlDataAdapter(com, conn);// Convert the database string to an sqldata adapter
DataTable dt = new DataTable(); // Create a data table for binding
numberOfModels = adpt.Fill(dt); // Determine number of models for this manufacturer before binding
if (numberOfModels > 0) // Fill the data table with the open Sql connection
{ // If models exist for this manufacturer
drpModel.DataSource = dt; // dropdownlist data source is newly created table
drpModel.DataTextField = "ModelName"; // relate database fields to dropdownlist fields
drpModel.DataValueField = "ModelID"; // Model ID goes in the value field
drpModel.DataBind(); // Data bind to the dropdown list in the front end
//hdnModelID.Value = "0"; // Indicate an unselected model exists
if (numberOfModels == 1) // If only one model (Special case)
{
BindGrid4BodyDetails(Convert.ToInt32(drpModel.SelectedValue)); // Bind the grid for body details for this model
}
hdnModelID.Value = drpModel.SelectedValue; // Indicate the only possible selection as the current ModelId value
}
else
{ // If no models exist for this manufacturer
hdnModelID.Value = "-1"; // Indicate this via hdnModelID value
drpModel.DataSource = null; // Bind null to the models to indicate no models
drpModel.DataTextField = "ModelName"; // relate database fields to dropdownlist fields
drpModel.DataValueField = "ModelID"; // Model ID goes in the value field
drpModel.DataBind(); // and clear any previous model data bound
}
conn.Close(); // Close the connection to the carsales database
}
Am I doing anything wrong inside the else statement? Why is it not binding null to the drop down list? Any help will be appreciated and the correct answer rewarded. Thanks.
Using drpModel.Items.Clear(); will explicity clear your items, but you shouldn't have to do this. You should be able to always bind the DataTable dt to the dropdown, even when there are no items in the result set. In this case, the DropDownList control will simply contain no items.
Change your code to the following:
public void BindModels(int manufacturer)
{
int numberOfModels;
string strConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString2"].ToString();
SqlConnection conn = new SqlConnection(strConnectionString);
conn.Open();
string com = "SELECT ModelID, ModelName From VehiclesModels Where ManufacturerID = " + manufacturer + " ";
SqlDataAdapter adpt = new SqlDataAdapter(com, conn);
DataTable dt = new DataTable();
numberOfModels = adpt.Fill(dt);
// set the DataTable as the DataSource, no items will be added to the DropDownList control if the DataTable has no records
drpModel.DataSource = dt;
drpModel.DataTextField = "ModelName";
drpModel.DataValueField = "ModelID";
drpModel.DataBind();
if (numberOfModels == 1)
{
BindGrid4BodyDetails(Convert.ToInt32(drpModel.SelectedValue));
}
hdnModelID.Value = drpModel.SelectedValue;
conn.Close();
}
use this code.
if (dt.Rows.Count > 0)
{
drpModel.DataSource = dt;
drpModel.DataTextField = "ModelName";
drpModel.DataValueField = "ModelID";
drpModel.DataBind();
}
How about this to go even one better: (One from the Baby Master):
public void BindModels(int manufacturer)
{
int numberOfModels;
string strConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString2"].ToString();
SqlConnection conn = new SqlConnection(strConnectionString); // Connect to Carsales database
conn.Open(); // Select all models for a particular make
string com = "SELECT ModelID, ModelName From VehiclesModels Where ManufacturerID = " + manufacturer + " ";
SqlDataAdapter adpt = new SqlDataAdapter(com, conn); // Convert the database string to an sqldata adapter
DataTable dt = new DataTable(); // Create a data table for binding
numberOfModels = adpt.Fill(dt);// Determine number of models for this manufacturer before binding
// Fill the data table with the open Sql connection
drpModel.DataSource = dt; // dropdownlist data source is newly created table
drpModel.DataTextField = "ModelName"; // relate database fields to dropdownlist fields
drpModel.DataValueField = "ModelID"; // Model ID goes in the value field
drpModel.DataBind(); // Data bind to the dropdown list in the front end
switch (numberOfModels)
{
case 0: hdnModelID.Value = "-1"; // If no models exist for this manufacturer, Indicate this via hdnModelID value
txtMessage.Text = "No models exist for this manufacturer"; // Give user a message.
break;
case 1 : BindGrid4BodyDetails(Convert.ToInt32(drpModel.SelectedValue)); // If only one model (Special case)
// Bind the grid for body details for this model
hdnModelID.Value = drpModel.SelectedValue; // Indicate the only possible selection as the current ModelId value
break;
default : break;
}
conn.Close(); // Close the connection to the carsales database
}

Make dropdown list reference 2 sql columns

There are 2 columns, one with name and the other with email addresses. I want to be able to display the names from the name's column in a dropdown but user the email in the next column when the form is submitted on my asp page.
public void FillAssignedToDropdownOnsite()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["onsite_db"].ConnectionString);
string query = "SELECT Name, EmailAddress FROM OnsiteData ";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
cmd.Connection.Open();
adpt.Fill(dt);
cmd.Connection.Close();
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataBind();
lstAssignedTo.Items.Insert(0, "Select Onsite Tech");
}
Sql table is OnsiteData
columns are name and emailaddress
Form has a dropdown that sends an email.
It seems that your tag is misplaced. Supposing that this is ASP.NET instead of ASP-Classic and lstAssignedTo is a DropDownList I suggest to use the DataValueField set to EmailAddress
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataValueField = "EMailAddress";
lstAssignedTo.DataBind();
when needed you could extract the email address for the selected user reading the Value property
if(lstAssignedTo.SelectedValue != null)
{
string email = lstAssignedTo.SelectedValue.ToString();
......
}
Not sure it's what you want :
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataValueField = "EmailAddress"
lstAssignedTo.DataBind();
lstAssignedTo.Items.Insert(0, "Select Onsite Tech");
Like this the name is displayed and you can get the corresponding email with
var value = lstAssignedTo.SelectedValue;

Categories

Resources