Listbox isn't populating with Data - c#

I have set up a listbox called lboxsupplier, i have also created a data adapter which i then used to populate the supplier listbox. When i run the form the listbox is empty. I want the listbox to populate with supplier ID and company which i will then click on to populate another listbox with products.
Namespace Pennyburn_Greg
{
public partial class FormProcess : Form
{
SqlDataAdapter daSupplier;
DataSet dsPennyburnGreg = new DataSet();
SqlConnection conn;
SqlCommand cmdSupplierDetails;
SqlCommandBuilder cmdBSupplier;
DataRow drSupplier;
String connstr, sqlSupplier;
public FormProcess()
{
InitializeComponent();
}
private void FormProcess_Load(object sender, EventArgs e)
{
connstr = #"Data Source= arlene-pc; Initial Catalog= PennyburnGreg; Integrated Security=True";
//dataAdapter for supplier listbox
sqlSupplier = #"Select* from Supplier";
conn = new SqlConnection(connstr);
cmdSupplierDetails = new SqlCommand(sqlSupplier, conn);
daSupplier = new SqlDataAdapter(cmdSupplierDetails);
daSupplier.FillSchema(dsPennyburnGreg, SchemaType.Source, "Supplier");
}
private void filllboxsupplier(string str)
{
daSupplier.Fill(dsPennyburnGreg, "Supplier");
lboxsupplier.DataSource = dsPennyburnGreg.Tables["Supplier"];
lboxsupplier.DisplayMember = "Company";
lboxsupplier.ValueMember = "SupplierID";
}
}
}

First of all, why are you calling FillSchema, rather should be calling Fill method to get the data, like
daSupplier.Fill(dsPennyburnGreg, "Supplier");
Once you have the dataset filled, then in your FormProcess_Load() you can add the dataset as datasource to the listbox like
lboxsupplier.DataSource = dsPennyburnGreg.Tables["Supplier"]

First thing you need to do is loosely couple your UI and data a little bit. Try this code:
// Returns a DataTable of ALL suppliers
private DataTable GetSuppliers()
{
return GetSuppliers(0);
}
// Returns a DataTable of the given supplier
private DataTable GetSuppliers(int supplierId)
{
using (var connection = new SqlCommand())
{
connection.ConnectionString = #"Data Source= arlene-pc; Initial Catalog= PennyburnGreg; Integrated Security=True";
using (var command = new SqlCommand())
{
connection.Open();
command.CommandType = CommandType.Text;
command.Connection = connection;
if (supplierId == 0)
{
command.commandText = "SELECT * FROM Supplier";
}
else
{
command.commandText = "SELECT * FROM Supplier WHERE SupplierId=#id";
command.Parameters.AddWithValue("#id", supplierId);
}
using (var adapter = new SqlDataAdapter())
{
using (var ds = new DataSet())
{
adapter.SelectCommand = command;
adapter.Fill(ds);
if (ds.Tables.Count > 0)
return ds.Tables[0];
}
}
}
}
return null;
}
And now you can just do this:
lboxsupplier.DataSource = GetSuppliers(int.Parse(lboxsupplier.SelectedValue));
lboxsupplier.DisplayMember = "Company";
lboxsupplier.ValueMember = "SupplierID";
Or if you need all Suppliers, just do this:
lboxsupplier.DataSource = GetSuppliers();
lboxsupplier.DisplayMember = "Company";
lboxsupplier.ValueMember = "SupplierID";
This code will provide some separation. This is still not ideal, but beats what you had.

You're not doing anything with the listbox control in FormProcess_Load, so it will be empty when it first loads. I'm assuming you have lboxsupplier_Click bound to the Click event of lboxsupplier? If so, then you'll need to click on that listbox before it will populate the Dataset (which is a very odd user experience, but if that's truly what you need...). If lboxsupplier_Click isn't an event handler, then you're going to have to manually call it.
If it still isn't populating, then try running your query against the database directly, and make sure that it returns data and has columns named "Company" and "SupplierID"

Related

How to get data from SQL and write it in textbox?

I need a help.
I searched and I tried a lot but I am too bad to make it work on my project by myself.
This is code for button-Seek. I want to make Seek-button to fill textbox by respective data.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
var Conn = new SqlConnection();
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
var Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = " + Number;
var DataAdapter = new SqlDataAdapter(Cmd);
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
}
}
And This is the data table.
This is what happens when I put 3 in the text box and press Seek-button.
So here, I want all text boxes to be filled by the data which I searched.
You will get only one row for the query right?
So give like that,
txtFirstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
txtLasttName.Text = DataSet.Tables[0].Rows[0]["LastName"].ToString();
Like this you need to assign the values to the respective text boxes.
There are three problem need to fix.
You forget to open the connection with DB,add Conn.Open(); before you excute sql command.
You need to add parameter to prevention SQL Injection
Please use using it will help you to use external resources to return the memory.
when the DataSet be filled you can get the data then fill in textbox
You can follow like this.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
using (var Conn = new SqlConnection())
{
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
using (var Cmd = new SqlCommand())
{
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = #Number";
Cmd.Parameters.AddWithValue("#Number", Number);
//You miss to add Conn.Open()
Conn.Open();
using (var DataAdapter = new SqlDataAdapter(Cmd))
{
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
//when the DataSet be filled you can get the data then fill in textbox
txt_firstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
}
}
}
}
}

Clearing data in SqlDataAdapter

I'm using SQLDataAdapter to populate data from my SQL server database in 2 DropDownLists. Depending on what is selected in the first dropdown, the corresponding data is populated in the second. It works fine but data that has since been deleted by the admin on their side of the application and is no longer in the database is still showing up in the dropdowns.
Is there a way in which I can reset or clear what is already in the DataAdapter, refresh it and then show only the current data?
If it helps here is how I have the data binding to the dropdowns. Firstly a general method which is called on page load to populate the first dropdown, and again in the _SelectedIndexChanged of the first dropdown to bind the relevant data to the second.
if (!IsPostBack)
{
DataBind();
string query = "select Distinct ClubID, ClubName from Pitch";
BindDropDownList(DDLClub, query, "ClubName", "ClubID", "Select Club");
DDLPitches.Enabled = false;
DDLPitches.Items.Insert(0, new ListItem("Select Pitch", "0"));
}
private void BindDropDownList(DropDownList DDL, string query, string text, string value, string defaultText)
{
string ConnString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
SqlCommand cmd = new SqlCommand(query);
using (SqlConnection con = new SqlConnection(ConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
con.Open();
DDL.DataSource = cmd.ExecuteReader();
DDL.DataTextField = text;
DDL.DataValueField = value;
DDL.DataBind();
sda.Dispose();
con.Close();
}
}
DDL.Items.Insert(0, new ListItem(defaultText, "0"));
}
protected void DDLClub_SelectedIndexChanged(object sender, EventArgs e)
{
DDLPitches.Enabled = false;
DDLPitches.Items.Clear();
DDLPitches.Items.Insert(0, new ListItem("Select Pitch", "0"));
int ClubID = int.Parse(DDLClub.SelectedItem.Value);
if (ClubID > 0)
{
string query = string.Format("select PitchID, ClubID, ClubName, PitchName from Pitch where ClubID = {0}", ClubID);
BindDropDownList(DDLPitches, query, "PitchName", "PitchID", "Select Pitch");
DDLPitches.Enabled = true;
}
}

Connection to SQL Server through ADO.NET - Empty Listbox

Trying to set up a connection to my local SQL Server Express instance so that I can display columns in a listbox. Th build runs fine and I can't see errors, but there is no data in the listbox. I have tested the query and that is fine. I am using NT Authentication to the database. Any ideas where I might have gone wrong?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void customers_SelectedIndexChanged(object sender, EventArgs e)
{
string commstring = "Driver ={SQL Server}; Server = DESKTOP-5T4MHHR\\SQLEXPRESS; Database = AdventureWorks2014; Trusted_Connection = Yes;";
string connstring = "SELECT FirstName, LastName FROM Person.Person";
SqlDataAdapter customerDataAdapater = new SqlDataAdapter(commstring, connstring);
DataSet customerDataSet = new DataSet();
customerDataAdapater.Fill(customerDataSet, "Person.Person");
DataTable customerDataTable = new DataTable();
customerDataTable = customerDataSet.Tables[0];
foreach (DataRow dataRow in customerDataTable.Rows)
{
customers.Items.Add(dataRow["FirstName"] + " (" + dataRow["LastName"] + ")");
}
}
}
I tested your code in a sample project here and I realized you passed the parameters to SqlDataAdapter constructor in a wrong order.
After changing the follow line:
SqlDataAdapter customerDataAdapater = new SqlDataAdapter(commstring, connstring);
by
SqlDataAdapter customerDataAdapater = new SqlDataAdapter(connstring, commstring);
the listbox was filled successfully.
Your connection string seems weird.....
Could you try using just this:
string commstring = "Server=DESKTOP-5T4MHHR\\SQLEXPRESS;Database=AdventureWorks2014;Trusted_Connection=Yes;";
Also: why are you first creating a DataSet, filling in a single set of data, and then extracting a DataTable from it?? This is unnecessarily complicated code - just use this instead:
SqlDataAdapter customerDataAdapater = new SqlDataAdapter(commstring, connstring);
// if you only ever need *one* set of data - just use a DataTable directly!
DataTable customerDataTable = new DataTable();
// Fill DataTable with the data from the query
customerDataAdapater.Fill(customerDataTable);
Update: I would really rewrite your code to something like this:
// create a separate class - call it whatever you like
public class DataProvider
{
// define a method to provide that data to you
public List<string> GetPeople()
{
// define connection string (I'd really load that from CONFIG, in real world)
string connstring = "Server=MSEDTOP;Database=AdventureWorks2014;Trusted_Connection=Yes;";
// define your query
string query = "SELECT FirstName, LastName FROM Person.Person";
// prepare a variable to hold the results
List<string> entries = new List<string>();
// put your SqlConnection and SqlCommand into "using" blocks
using (SqlConnection conn = new SqlConnection(connstring))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
// iterate over the results using a SqlDataReader
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// get first and last name from current row of query
string firstName = rdr.GetFieldValue<string>(0);
string lastName = rdr.GetFieldValue<string>(1);
// add entry to result list
entries.Add(firstName + " " + lastName);
}
rdr.Close();
}
conn.Close();
}
// return the results
return entries;
}
}
And in your code-behind, you only need to do something like this:
protected override void OnLoad(.....)
{
if (!IsPostback)
{
List<string> people = new DataProvider().GetPeople();
customers.DataSource = people;
customers.DataBind();
}
}
but I still don't understand what you were trying to when the SelectedIndexChanged event happens.....

Update mysql database from datagridview selected row

i have a datagridview which loads mysql database table t_pi_clients on form load event,and i have another tab which contains textboxes of the respective columns of t_pi_client, which am able to get data from fullrowselect mode into those textboxes. now i want to update the database upon changes in the those textbox values. so far i've tried some process and gets my "entry saved" messageBox.show but nothing happens to database, so am hoping someone could help me out maybe am missing something thanks
public partial class frmMain : Form
{
MySqlConnection connection;
MySqlDataAdapter mySqlDataAdapter;
DataSet dt = new DataSet();
DataSet DS = new DataSet();
DataSet dg = new DataSet();
public frmMain()
{
InitializeComponent();
}
#region Main load
private void frmMain_Load(object sender, EventArgs e)
{
var connectionString = ConfigurationManager.ConnectionStrings["Pigen"].ConnectionString;
connection = new MySqlConnection(connectionString);
if (this.OpenConnection() == true)
{
mySqlDataAdapter = new MySqlDataAdapter("select * from t_pi_Clients", connection);
DataSet DS = new DataSet();
mySqlDataAdapter.Fill(DS);
kryptonDataGridView1.DataSource = DS.Tables[0];
kryptonDataGridView1.Columns[0].Visible = false;
mySqlDataAdapter = new MySqlDataAdapter("select * from t_pi_msg_charge_Rate", connection);
DataSet dt = new DataSet();
mySqlDataAdapter.Fill(dt);
kryptonDataGridView2.DataSource = dt.Tables[0];
mySqlDataAdapter = new MySqlDataAdapter("select * from t_pi_client_deposits", connection);
DataSet dg = new DataSet();
mySqlDataAdapter.Fill(dg);
kryptonDataGridView3.DataSource = dg.Tables[0];
}
}
//loads selected row data into textboxes
private void kryptonDataGridView1_DoubleClick(object sender, EventArgs e)
{
textboxClientCode.Text = kryptonDataGridView1.SelectedRows[0].Cells["ClientCode"].Value.ToString();
txtboxClientName.Text = kryptonDataGridView1.SelectedRows[0].Cells["ClientName"].Value.ToString();
txtboxPostalAddress.Text = kryptonDataGridView1.SelectedRows[0].Cells["PostalAdd"].Value.ToString();
txtboxTelephone.Text = kryptonDataGridView1.SelectedRows[0].Cells["Telephone"].Value.ToString();
txtboxFax.Text = kryptonDataGridView1.SelectedRows[0].Cells["Fax"].Value.ToString();
txtboxEmailAddress1.Text = kryptonDataGridView1.SelectedRows[0].Cells["EmailAdd1"].Value.ToString();
txtboxEmailAddress2.Text = kryptonDataGridView1.SelectedRows[0].Cells["EmailAdd2"].Value.ToString();
txtboxEmailAddress3.Text = kryptonDataGridView1.SelectedRows[0].Cells["EmailAdd3"].Value.ToString();
txtboxWebsite.Text = kryptonDataGridView1.SelectedRows[0].Cells["Website"].Value.ToString();
txtboxChargeRate.Text = kryptonDataGridView1.SelectedRows[0].Cells["ChargeRate"].Value.ToString();
txtboxTotalDepo.Text = kryptonDataGridView1.SelectedRows[0].Cells["TotalDeposit"].Value.ToString();
txtboxAccountBal.Text = kryptonDataGridView1.SelectedRows[0].Cells["AccountBal"].Value.ToString();
txtboxEntrydate.Text = kryptonDataGridView1.SelectedRows[0].Cells["EntryDate"].Value.ToString();
}
now i tried this method to update but doesn't update database
private void kryptonbtnUpdate_Click(object sender, EventArgs e)
{
var connectionString = ConfigurationManager.ConnectionStrings["Pigen"].ConnectionString;
using (MySqlConnection Conn = new MySqlConnection(connectionString))
if (Conn.State.ToString() != "Open")
{
}
else
{
connection.Open();
}
try
{
DataTable changes = ((DataTable)kryptonDataGridView1.DataSource).GetChanges();
if (changes != null)
{
MySqlCommandBuilder mcb = new MySqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.UpdateCommand = mcb.GetUpdateCommand();
mySqlDataAdapter.Update(changes);
((DataTable)kryptonDataGridView1.DataSource).AcceptChanges();
mySqlDataAdapter.Update(DS);
}
// adapter.Update(rowsToUpdate);
// mySqlDataAdapter.Update(DS);
MessageBox.Show("Entry Saved");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This is just a pseudocode of what you need to do
string cmdText = #"UPDATE t_pi_Clients
SET ClientName = #ClientName,
PostalAdd = #PostalAdd,
Telephone = #Telephone,
Fax = #Fax,
.... etc ....
WHERE ClientCode = #ClientCode";
using(MySqlConnection cn = new MySqlConnection(.....))
using(MySqlCommand cmd = new MySqlCommand(cmdText, cn))
{
cn.Open();
cmd.Parameters.AddWithValue("#ClientName", txtboxClientName.Text);
cmd.Parameters.AddWithValue("#PostalAdd", txtboxPostalAddress.Text);
....etc etc...
cmd.Parameters.AddWithValue("#ClientCode", textboxClientCode.Text);
int rowsUpdated = cmd.ExecuteNonQuery();
if(rowsUpdated > 0)
{
// extract the code that loads DataGridView1 from the Form_Load
// and create a reusable method that you could call from here
}
}
First you build an sql command text with the UPDATE clause. I assume that your primary key (the field that uniquely identifies your records) is the ClientCode field.
Then create the connection and the command. Fill the command parameters collection with the parameters required by your text taking the values from the TextBoxes.
Call the ExecuteNonQuery to store the values.
If you succeed then you need to update or reload your datagridview. The best approach would be setting one by one the gridview cells of the current row with the new values from the textboxes, or you could simply extract the code used in form_load to fill the grid and make a new method that you could call from the button click event. (But this could be slower if you have many records)

Attach a SQL database to ComboBox.ItemSource (WPF)

I want to know how can I assign a SQL Server database to ItemSource property of a ComboBox (in a WPF app). I assigned the data source to the project but do not know how to assign to the property.
Best regards
you can try like this ..you can bind the item source property of combobox like this below..
ItemsSource="{Binding}"
EDIT:
Connection string :
You can add in control event or class but it should be in wpf application window.
If you create new application in visual studio or visual c# or whatever it creates window1.xaml. you need to add connection string basically in class or event in that window1.xaml not in app.config or app.xaml.
connection string define in class:
Here is example by creating a class (its sql connector instead of OleDb which i showed in 1st one):
public class ConnectionHelper
{
public static SqlConnection GetConnection()
{
string connectionStr = "Data Source=MICROSOFT-JIGUO;Initial Catalog=CompanyTestDB;Integrated Security=True";
SqlConnection conn = new SqlConnection(connectionStr);
return conn;
}
}
and you can use this class in your methods:
SqlConnection conn = ConnectionHelper.GetConnection();
<Window
.......
Loaded="OnLoad"
>
<Grid>
<ComboBox Height="18" SelectionChanged="cmbCategory_SelectionChanged"
ItemsSource="{Binding}"
HorizontalAlignment="Right" Margin="0,92,17,0" Name="cmbCategory"
VerticalAlignment="Top" Width="176"
BorderBrush="#FFFFFFFF" SelectedIndex="0"/>
</Grid>
</Window>
on load function u can assign values to combobox
private void OnLoad(object sender, System.EventArgs e)
{
ListCategories();
}
private void ListCategories()
{
sqlCon = new SqlConnection();
sqlCon.ConnectionString = Common.GetConnectionString();
cmd = new SqlCommand();
cmd.Connection = sqlCon;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM Categories";
sqlDa = new SqlDataAdapter();
sqlDa.SelectCommand = cmd;
ds = new DataSet();
try
{
sqlDa.Fill(ds, "Category");
DataRow nRow = ds.Tables["Category"].NewRow();
nRow["CategoryName"] = "List All";
nRow["CategoryID"] = "0";
ds.Tables["Category"].Rows.InsertAt(nRow, 0);
//Binding the data to the combobox.
cmbCategory.DataContext = ds.Tables["Category"].DefaultView;
//To display category name (DisplayMember in Visual Studio 2005)
cmbCategory.DisplayMemberPath =
ds.Tables["Category"].Columns["CategoryName"].ToString();
//To store the ID as hidden (ValueMember in Visual Studio 2005)
cmbCategory.SelectedValuePath =
ds.Tables["Category"].Columns["CategoryID"].ToString();
}
catch (Exception ex)
{
MessageBox.Show("An error occurred while loading categories.");
}
finally
{
sqlDa.Dispose();
cmd.Dispose();
sqlCon.Dispose();
}
}
If someone else lands up here(like I did), here is the improved version of pratap k's code. Just pass 6 parameters to this method and it will fill your comboBox.
connectionString - name of the connection string to connect to the DB. If you prefer to set it up in another class and just call
the reference, you can modify the code accordingly.
combobox - Name of the comboBox you want to fill
query - You query to fetch the data from the database
defaultValue - The default value you want to set to the comboBox
itemText - This the data you want to show in the list box. This is the name of the column of the DB and is in your SELECT query.
itemValue - This is the value you want to associate to the items of the combobox. This is also a column in your SELECT query and is the name of a column in your db. (If you don't need it, remove it from the code and the parameter too.
Also, you can pass these to values (DisplayMemberPath and SelectedValuePath) in your XAML code.
public bool fillComboBox(string connectionString, System.Windows.Controls.ComboBox combobox, string query, string defaultValue, string itemText, string itemValue)
{
SqlCommand sqlcmd = new SqlCommand();
SqlDataAdapter sqladp = new SqlDataAdapter();
DataSet ds = new DataSet();
try
{
using (SqlConnection _sqlconTeam = new SqlConnection(ConfigurationManager.ConnectionStrings[connectionString].ConnectionString))
{
sqlcmd.Connection = _sqlconTeam;
sqlcmd.CommandType = CommandType.Text;
sqlcmd.CommandText = query;
_sqlconTeam.Open();
sqladp.SelectCommand = sqlcmd;
sqladp.Fill(ds, "defaultTable");
DataRow nRow = ds.Tables["defaultTable"].NewRow();
nRow[itemText] = defaultValue;
nRow[itemValue] = "-1";
ds.Tables["defaultTable"].Rows.InsertAt(nRow, 0);
combobox.DataContext = ds.Tables["defaultTable"].DefaultView;
combobox.DisplayMemberPath = ds.Tables["defaultTable"].Columns[0].ToString();
combobox.SelectedValuePath = ds.Tables["defaultTable"].Columns[1].ToString();
}
return true;
}
catch (Exception expmsg)
{
return false;
}
finally
{
sqladp.Dispose();
sqlcmd.Dispose();
}
}
Thanks pratap k. :)

Categories