How to set up BindingNavigator? - BindingNavigator is not working - c#

I have a data app that uses a BindingNavigator. I have hooked up the navigator to a binding source, however it is not working. It will not add or delete rows. The binding source is: accountBindingSource. I don't understand what is wrong. I have the following code:
public partial class AccountDataGridView : Form
{
public AccountDataGridView()
{
InitializeComponent();
Setup();
}
private void AccountDataGridView_Load(object sender, EventArgs e)
{
// Change the back color of the first column. This can also be changed in the designer
accountGridView.Columns[0].DefaultCellStyle.BackColor = Color.FromArgb(192, 192, 255);
}
private void Setup()
{
// Define a global variable for the data table
Account = new DataTable(Text);
query = string.Format("SELECT * FROM {0}", Text);
// Establish a connection between the Database and the form
conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Tutoring Database.accdb;Persist Security Info=False");
conn.Open();
// Setup data table
OleDbDataAdapter accountAdapter = new OleDbDataAdapter(query, conn);
if (accountAdapter != null)
{
accountAdapter.Fill(Account);
}
accountGridView.DataSource = Account;
conn.Close();
}
private void DataErrorRaised(object sender, DataGridViewDataErrorEventArgs e)
{
// Data table error handling. This is triggered when the user attempts to input invalid data into the CurrentBalance column
MessageBox.Show("You have entered an invalid data type for the currency column. Please enter text formatted like so: '$0.00'",
"Account Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
}
private void btnSave_Click(object sender, EventArgs e)
{
// Update Access Database
try
{
adapter.SelectCommand = new OleDbCommand(query, conn);
adapter.InsertCommand = new OleDbCommand(query, conn);
adapter.DeleteCommand = new OleDbCommand(query, conn);
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
adapter.Update(Account);
Console.WriteLine("Saved");
}
catch
{
}
}
private DataTable Account;
private string query;
private OleDbConnection conn;
private OleDbDataAdapter adapter = new OleDbDataAdapter();
private void accountGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
btnSave_Click(null, null);
}
}

In your question you assigned data to accountGridView.DataSource. So you can not expect the binding navigator work. The BindingSource is not connected to data and the BindingNavigator and DataGridView are not connected to the BindingSource.
You should perform these settings using designer or code:
Load data and assign data to DataSource property of BindingSource. (Using code)
Assign BindingSource to DataSource property of your DataGridView
Assign BindingSource to BindingSource property of the BindingNavigator.
Note
Changing query has nothing to do with binding source. The BindingSource and BindingNavigator work regardless of the adapter or anything which provides/saves data. Neither BindingSource nor BindingNavigator are not aware about where the data comes from actually and how the data will be saved.

I just solved my problem by creating a new BindingSource and setting its properties through code. To do this, simply drag a BindingSource onto the form. Name it whatever you would like. In the code part of your solution type something similar to this (in the constructor).
BindingSource.DataSource = Account;
Make sure to set your BindingNavigator's BindingSource to the BindingSource you just created. Thank you for the help, everyone!
EDIT: I don't know if this had anything to do with my solution but I also edited my queries a little bit. This code is mandatory for the project to work.
try
{
adapter.SelectCommand = new OleDbCommand(query, conn);
adapter.InsertCommand = new OleDbCommand("INSERT INTO Account (AccountNumber, LastName, FirstName, CurrentBalance) " +
"VALUES (?, ?, ?, ?)", conn);
adapter.DeleteCommand = new OleDbCommand(query, conn);
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
adapter.Update(Account);
Console.WriteLine("Saved");
}
catch
{
}

For posterity:
BindingNavigator's buttons are lightweight controls, unlike a real Button control.
When you click any button in the BindingNavigator, the Focus is not stolen from the current Control, and thus the sequence of events that lead to the data being pushed to the underlying database is never called.
I know I had an example of a few lines of code you had to put in each of those lightweight button's Click handler, but can't find it for now.
This has always been a PITA!

Related

Refresh datagridview from another user control

Using C# and Winform.
I read a couple of similar questions but couldn't find any great answers that could interlock with my code. So, bear with me and thank you in advance for helping me.
I have a single form that contains multiple User Controls. Inside the first user control, you can insert, update and delete records from the database. In the second User Control, there is a datagridview that is populated with all records.
The problem I have is that whenever I insert, update or delete a record inside the first user control. It won't refresh inside the datagridview when I swap to the second user control.
Beneath is the second user control that populates the datagridview
private void populate()
{
database.OpenConnection();
string query = "SELECT id, name, qoute, time, date from maintable";
SQLiteDataAdapter sda = new SQLiteDataAdapter(query, database.connection);
SQLiteCommandBuilder builder = new SQLiteCommandBuilder(sda);
var ds = new DataSet();
sda.Fill(ds);
dtgNav.DataSource = ds.Tables[0];
databas.CloseConnection();
}
private void Navigation_Load(object sender, EventArgs e)
{
populate();
dtgNav.Columns[0].HeaderText = "ID";
}
public void Refresh()
{
this.Refresh();
}
Beneath is the code for adding a record to the datagridview in the first user control
private void btnAdd_Click(object sender, EventArgs e)
{
database.OpenConnection();
string query = "INSERT INTO maintable (`id`, `name`, `qoute`, `time`,`date`) VALUES (#Id, #Name, #Qoute, #Time, #Date)";
SQLiteCommand command = new SQLiteCommand(query, database.connection);
command.Parameters.AddWithValue("#Id", tbxID.Text);
command.Parameters.AddWithValue("#Name", tbxName.Text.Trim());
command.Parameters.AddWithValue("#Qoute", tbxQoute.Text.Trim());
command.Parameters.AddWithValue("#Time", tbxTime.Text.Trim());
command.Parameters.AddWithValue("#Date", dtpDate.Value.ToString("yyyy-MM-dd"));
command.ExecuteNonQuery();
MessageBox.Show("Added new event into the database.");
database.CloseConnection();
usercontrol2.Refresh();
}
I would appreciate it if we found a way to refresh the datagridview when the button is clicked without changing the original code all too much.
You have a public void Refresh method in the second usercontrol, try modifying this.Refresh();, to say populate();. this should call your private void populate method that you called when loading which should reload the grid. Let me know if this helps.

How can I populate a textbox with database values from a combobox?

I am quite new to C# and I am trying to populate fill several textboxes with data from a selected combobox.
I have my main window with the textboxes and comboboxes and a separate class for the connection to the database (I am using XAMPP/PhpMyAdmin).
I managed to fill the comboboxes with the data from the database, but I cannot fill the texboxes from the selected combobox.
I checked other questions and tutorials, but all I managed to achieve is to get the primary key into the text box, but I need different columns from the table, depending on the textbox.
I populated the combobox from the database:
void Completez_Combo_Furnizor()
{
combo_furnizor = DB_Furnizori.Combo_Furnizor();
comboBoxFurnizor.Items.Clear();
comboBoxFurnizor.DataSource = combo_furnizor;
comboBoxFurnizor.ValueMember = "id_furnizor";
comboBoxFurnizor.DisplayMember = "nume";
}
I double clicked on the combobox and wrote the following, but all I can get is the primary key (the first column). In the textbox, I need to get the 7th column (which is a double type.
private void comboBoxFurnizor_SelectedIndexChanged(object sender, EventArgs e)
{
textBoxPret.Text = comboBoxFurnizor.SelectedItem.ToString();
}
And this is from the database class (DB_Furnizori.cs), where I open the connection and have multiple queries for the database.
public static DataTable Combo_Furnizor()
{
conn.Open();
MySqlCommand comboFurnizor = new MySqlCommand("SELECT * from furnizori ORDER BY nume", conn);
MySqlDataAdapter adaptc = new MySqlDataAdapter(comboFurnizor);
DataTable combo_furnizori = new DataTable();
adaptc.Fill(combo_furnizori);
conn.Close();
return combo_furnizori;
}
Please help.
For your SelectedIndexChanged Method :
private void comboBoxFurnizor_SelectedIndexChanged(object sender, EventArgs e)
{
textBoxPret.Text = comboBoxFurnizor.SelectedItem.ToString();
}
You need to make another call to the database and retrieve the data you want using the values/Id (or whatever is the unique identifier) from the combobox. If you're trying to retrieve data on a selected index change you need to reference some type of data source for me I used a DataSet instead of DataTable (makes retrieving values in cells easier):
string StoredProc = "GetItemNotes";
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(StoredProc, conn);
SqlDataAdapter da = new SqlDataAdapter();
cmd.CommandType = CommandType.StoredProcedure;
da.SelectCommand = cmd;
da.Fill(ds);
For populating the data within my Textbox I did this:
Notes.Text = ds.Tables[0].Rows[0]["Notes"].ToString();

Changes to DataGridView aren't being reflected in database

I have a DataGridView control and a save button. When the Save button is clicked, I want any changes made to the DataGridView to be reflected in my database via a DataAdapter Update() command. However, after hitting the save button and reloading the form, the updates are not there.
Here is all the code for the Save button currently:
private void btnSave_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=addtool.database.windows.net;Initial Catalog=AddToolToInventoryDB;User id=kanerbw; Password=Rabaraba!11;");
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter("select * from ToolTB", con);
SqlCommandBuilder myBuilder = new SqlCommandBuilder(adapter);
con.Open();
SqlCommandBuilder scb = new SqlCommandBuilder(adapter);
myBuilder.GetUpdateCommand();
adapter.UpdateCommand = myBuilder.GetUpdateCommand();
adapter.Update(dt);
con.Close();
}
EDIT: I had forgotten to set the datasource of my DGV to the datatable. Here's the working code:
private void btnSave_Click(object sender, EventArgs e)
{
using (var con = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter("select * from ToolTB", con);
SqlCommandBuilder myBuilder = new SqlCommandBuilder(adapter);
dgvProductInfo.DataSource = dt;
adapter.UpdateCommand = myBuilder.GetUpdateCommand();
adapter.Update(dt);
dt.Clear();
adapter.Fill(dt);
}
}
Your code has several problems:
You are not enclosing the SQLConnection in a using statement. You should always use this pattern so that the connection is properly disposed: using(var connection = new SqlConnection(...)){ rest of statements here }
On the btnSave_Click function, you are getting the data again from the database -see the select * from tbl... code- and you are populating the DataTable again; therefore, it's obvious that there won't be any changes reflected. What you need to do instead is read the Updated DataTable from the page and use it inside the btnSave_Click function to push the updates to the database.
Your question refers to DataGridView which I believe is a User Control on WinForms, but your question is tagged as ASP.NET. Are you referring to a GridView control instead? Either way, both controls should have a way of getting the DataSource bound to them. You should be able to use that DataSource to push the updates to the database.
I hope this pointers are helpful. I cannot be more specific given the code you provided in your question.

Editing contents of a listbox that is populated by a sql query datasource using c#

I have a list box that is populated by a query result set, i would to give the user the ability to edit the contents of the list box, and update the database back end, how can i achieve this?
public Brand_Manager(Main parent)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlConn"].ConnectionString.ToString());
SqlCommand cmd = new SqlCommand("select Brand_ID, Brand_Name from Brand where status=1", conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable t = new DataTable();
da.Fill(t);
listBox1.DisplayMember = "Brand_Name";
listBox1.DataSource = t;
listBox1.ValueMember = "Brand_ID";
conn.Close();
}
private void Edit_Button_Click(object sender, EventArgs e)
{
this.Edit_Button.Enabled = false;
object item = listBox1.SelectedItem;
Edit_Brand frm = new Edit_Brand();
this.AddOwnedForm(frm);
frm.ShowDialog();
}
Do you use WPF or WinForms? Anyway you need to investigate Bindings: BindingSource in WinForms or Binding class in WPF (http://msdn.microsoft.com/en-us/library/ms750612.aspx).
Look at DataTable events http://msdn.microsoft.com/en-us/library/system.data.datatable_events.aspx . There is RowChangedEvent. Call update sql command in its handler.
You need to use datagridview for this purpose. It is designed for this purpose. You can assign the datasource to gridview and allow user to edit rows. Then by handling row edited event or by giving the button you can update the database. See an example here

Display tables from SQL in DataGridView

I created a DataBase named charityah containing 5 tables. Their names are listed in a combobox.
When I choose one of them I want to display their content in a DataGridView.
What I tried is: first I linked the DataGridView to this database and tried this code that I found:
SqlConnection connection = new SqlConnection();
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string s = comboBox1.Text;
connection.ConnectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Downloads\charityah.mdf;Integrated Security=True";
using (connection)
{
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter("select * from "+s, connection);
DataSet ds = new DataSet();
adapter.Fill(ds, s);
dataGridView1.DataSource = ds.Tables[0];
dataGridView1.Refresh();
}
}
This method doesn't give me any errors and it finds the tables, but nothing is seen in the DataGridView.
Since you report (comments) that there are rows, it sounds like the primary problem (connection disposal aside) is an issue with data-binding. A few thoughts leap to mind:
is the table in virtual mode?
is it adding columns?
do the columns already exist?
You might want to try adding:
dataGridView1.VirtualMode = false;
dataGridView1.Columns.Clear();
dataGridView1.AutoGenerateColumns = true;
before the:
dataGridView1.DataSource = ds.Tables[0];
You might also want to check that dataGridView1.DataMember doesn't have a value assigned.
try this, some times nonsense items do create a lot of mess. so try setting autogenerate columns to true. may this starts showing you the results. because as per your comments, it dosent seems there could be any other issue. so just give it a try
dataGridView1.AutoGenerateColumns = true;

Categories

Resources