DataSet dataSet = new DataSet();
using (SqlConnection connection = new SqlConnection("server=server; database=database; user id=user; password=user"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT DISTINCT ID FROM TABLE ORDER BY ID ASC", connection))
{
SqlDataAdapter reader = new SqlDataAdapter(command);
reader.Fill(dataSet);
IDComboBox.DataContext = dataSet; --> This doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Columns[0].ToString() --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Rows[0].ToString() --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Rows --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Columns --> doesn't work
They don't work even with me pairing it the IDComboBox.DataContext = dataSet.Tables[0].Rows[0] or Columns[0]
}
connection.Close();
connection.Dispose();
}
I am needing to fill my combobox in a WPF with the data from my datatable. All I keep finding are the examples that use Combobox.Displaymember, Combobox.Source to do this but a C# WPF application doesn't have these options. How can I load a WPF combobox with data from a dataset or a datatable?
One way that I was doing it before was
using (SqlConnection connection = new SqlConnection("server=server; database=database; user id=user; password=user"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT DISTINCT ID FROM Table ORDER BY ID ASC", connection))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
IDComboBox.Items.Add(reader[i].ToString());
}
}
}
connection.Close();
connection.Dispose();
}
I know having it for looped into my combobox is very slow if I have large amounts of data so I am wanting to dump it in from a dataset to reduce run time.
Derived from this example, you'll want to work with the ItemSource, DisplayMemberPath, and SelectedValuePath properties:
IDComboBox.ItemsSource = dataSet.Tables[0].DefaultView;
IDComboBox.DisplayMemberPath = dataSet.Tables[0].Columns["ID"].ToString();
IDComboBox.SelectedValuePath = dataSet.Tables[0].Columns["ID"].ToString();
And in xml:
<ComboBox Name="IDComboBox" ItemsSource="{Binding}"/>
The WPF ComboBox has an ItemSource property you can use.
IDComboBox.ItemsSource = dataSet.Tables[0].Rows;
Related
I would like to know how to insert selected items from a ListBox into a MSSQL Database.
I am developing an ASP.NET web app and this is the problem:
I have a Listbox named lbxRuoli and items are loaded directly from the database:
SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", conn);
SqlDataReader dr = cmd.ExecuteReader();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
while (dr.Read())
{
li = new ListItem(dr["descrizione_Ruoli"].ToString(), dr["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
dr.Close();
cmd.Dispose();
Now it comes to write the INSERT for the selected items:
for (int i = 0; i < lbxRuoli.Items.Count; i++)
{
if (lbxRuoli.Items[i].Selected == true)
{
cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", conn);
cmd.Parameters.AddWithValue("#id", txtId.Text);
cmd.Parameters.AddWithValue("#idR", lbxRuoli.SelectedValue);
cmd.ExecuteNonQuery();
}
}
It happens that I only insert the same first selected item for the total numbers of the selected items.
It would be wonderful if someone can help me!
Thanks to every one in advance!
Connections need to be not only closed but disposed to release unmanaged objects. using blocks handle this even if there is an error.
Commands also need to be disposed. To accomplish this they should be declared local to the method where they are used. using blocks will close and dispose you database objects.
You don't want to hold a connection open while you update the user interface. Fill a DataTable, close the connection (the using block does it) and then fill the ListBox from the DataTable.
To insert the data create the connection, command and fill the parameters collection outside the loop. Only the values of the parameters change inside the loop
The code below demonstrates how to use the .Add method for parameters. I had to guess at the type and size of the parameters. Check your database and adjust the code accordingly making sure that the parameter values are compatible with the SqlDbType.
private string ConStr = "Your connection string";
private DataTable GetListData()
{
DataTable dt = new DataTable();
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", cn))
{
cn.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
private void FillListBox()
{
DataTable dt = GetListData();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
foreach (DataRow row in dt.Rows)
{
li = new ListItem(row["descrizione_Ruoli"].ToString(), row["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
}
private void InsertData()
{
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", cn))
{
cmd.Parameters.Add("#id", SqlDbType.VarChar, 20);
cmd.Parameters.Add("#idR", SqlDbType.VarChar, 20);
cn.Open();
foreach (ListItem li in lbxRuoli.Items)
{
if (li.Selected)
{
cmd.Parameters["#id"].Value = li.Text;
cmd.Parameters["idR"].Value = li.Value;
cmd.ExecuteNonQuery();
}
}
}
}
When I check more than one item in the CheckedListBox, than it only gets the Selected.Value of the last selected item and uses that for the amount of times the foreach is used.
Extra context: It's an application that can put exercises on certain days, so it's a workout app, but when you select more than 1 exercise in the CheckedListBox, than it only adds items with the last selected value.
So selects 3 different items(pushups, pullups, situps) --> 3 situps get added with all the same values.
Code that adds exercises to the other normal ListBox:
query = "INSERT INTO Xercise_Day (DayId, ExerciseId) " +
"VALUES(#DayId, #ExerciseId)";
foreach (CheckedListBox exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", clbXcercises.SelectedValue);
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}
for(int i = 0; i < clbXcercises.Items.Count; i++)
{
clbXcercises.SetItemChecked(i, false);
}
As stated in the comments, reference exercise instead of clbXcercises to get the selected value. The code becomes:
foreach (object exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", exercise.ToString());
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}
I want to make Autocomplete in a ComboBox using Access 2017. So I used this code... But there are some errors, like:
"The name 'da' does not exist in the current context".
Please help me to fix this error.
private void Autocomplete()
{
string query;
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Neth1.accdb");
//opening connection
con.Open();
try
{
//initialize a new instance of sqlcommand
OleDbCommand cmd = new OleDbCommand();
//set a connection used by this instance of sqlcommand
cmd.Connection = con;
//set the sql statement to execute at the data source
cmd.CommandText = query;
OleDbDataAdapter da = new OleDbDataAdapter();
//set the sql statement or stored procedure to execute at the data source
da.SelectCommand = cmd;
//initialize a new instance of DataTable
DataTable dt = new DataTable();
//add or resfresh rows in the certain range in the datatable to match those in the data source.
da.Fill(dt);
foreach (DataRow r in dt.Rows)
{
//getting all rows in the specific field|Column
var rw = r.Field<string>("IMEI");
//Set the properties of a combobox to make it auto suggest.
comboBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
//adding all rows into the combobox
comboBox1.AutoCompleteCustomSource.Add(rw);
}
}
catch (Exception ex)
{
//catching error
MessageBox.Show(ex.Message);
}
//release all resources used by the component
da.Dispose();
//clossing connection
con.Close();
}
Your OleDbDataAdapter da = new OleDbDataAdapter(); is within try { } scope and
da.Dispose(); is outside of that scope, try to place this line within try { } scope or move OleDbDataAdapter da = new OleDbDataAdapter(); outside of try { }scope.
Your OleDbDataAdapter is declare inside the try block, it doesn't exist outside of it, hence the error you're seeing.
The query string presented here is empty.
When you deal with OleDb objects, it's common practice to make use
of using blocks, which take care of disposing the disposable objects you create.
What you rally don't want, is to set those controls properties inside a foreach loop.
It is also more efficient to fill the ComboBox AutoCompleteCustomSource using AddRage(), instead of adding objects one by one.
This is how I propose to edit your code:
// You can set these properties in the Form designer
comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
// [...]
string query = "SELECT [Some Field] FROM [Some Table] WHERE [Some Condition]";
List<string> data = new List<string>();
try {
using (var con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Neth1.accdb"))
{
con.Open();
using (var cmd = new OleDbCommand(query, con))
using (var reader = cmd.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
data.Add((string)reader["IMEI"]);
}
}
}
}
}
catch {
// Notify, log, whatever fits
}
comboBox1.AutoCompleteCustomSource.Clear();
comboBox1.AutoCompleteCustomSource.AddRange(data.ToArray());
data.Clear();
I'm just learning and have written this code to copy data from one database to another (LOTSCON) = source, CON = destination.
The code all works and copies the data across, however it is based on checkboxes on a previous datagridview form.
The user selects which records to import, but also selects CHKCOMMUNITY which means this patient is a nursing home patient.
In the NEW table, there is a column nursinghome which is a bit type.
If the user ticks chkCommunity in the datagrid, I want to do the bulk copy but also make sure the nursinghome column in the destination table is set to 1.
So I'm not mapping an existing column in the source table..
How can I achieve this?
DO I just import then run a SQL string updating the column based on what I have just entered?
foreach (DataGridViewRow row in dataGridInst.Rows)
{
DataGridViewCheckBoxCell chkcell = row.Cells["chkimport"] as DataGridViewCheckBoxCell;
if (chkcell.Value != null)
{
if (Convert.ToBoolean(chkcell.Value) == true)
{
instid = Convert.ToInt32(row.Cells["clninstid"].Value);
iscommunity = Convert.ToInt32(row.Cells["chkcommunity"].Value);
using (SqlConnection lotscon = new SqlConnection(ConfigurationManager.ConnectionStrings["LOTSConnectionString"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(#"SELECT Person.*, NEWinstitution.institutionname
FROM NEWinstitution INNER JOIN Person ON NEWinstitution.institutionid = Person.InstitutionID
WHERE person.institutionid = #instid", lotscon))
{
cmd.Parameters.Add("#instid", SqlDbType.Int).Value = instid;
using (SqlDataAdapter adapt = new SqlDataAdapter())
{
adapt.SelectCommand = cmd;
lotscon.Open();
DataSet ds = new DataSet();
adapt.Fill(ds);
DataTable dtgenerate = new DataTable();
dtgenerate = ds.Tables[0];
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString))
{
using (SqlBulkCopy bc = new SqlBulkCopy(con))
{
bc.DestinationTableName = "tblpatient";
bc.ColumnMappings.Add("firstname", "pxfirstname");
bc.ColumnMappings.Add("lastname", "pxlastname");
bc.ColumnMappings.Add("address", "address");
bc.ColumnMappings.Add("suburb", "suburb");
bc.ColumnMappings.Add("medicareno", "medicarenumber");
bc.ColumnMappings.Add("personid", "dispenseid");
bc.ColumnMappings.Add("institutionname", "institutionname");
bc.ColumnMappings.Add("VAcardid", "repatnumber");
bc.ColumnMappings.Add("phonenumber", "phonenumber");
con.Open();
bc.WriteToServer(dtgenerate);
con.Close();
lotscon.Close();
}
}
}
}
}
}
}
}
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"