I need to update selected row in datagrid when i click on button Ponuda.
The problem is, when i click on button, nothing happens, but when i restart application, whole list is updated. So i need a way to update only the row i have selected and to update it right away and not after application restart.
This is my code for button click :
private void button3_Click(object sender, RoutedEventArgs e)
{
// count = 120;
// tmr.Start();
using (SqlConnection conn = new SqlConnection(#"data source=ZC-PC\SQLEXPRESS;database=Aukcija;integrated security=true;"))
{
DataTable cena1 = new DataTable();
conn.Open();
SqlDataAdapter DA = new SqlDataAdapter(" UPDATE Predmet SET trenutnaCena = trenutnaCena + 1", conn);
SqlCommand cmd = new SqlCommand("UPDATE Predmet SET trenutnaCena = trenutnaCena + 1", conn);
cmd.ExecuteNonQuery();
DA.Update(cena1);
conn.Close();
}
}
If you are using bindings, it SHOULD be updating. The reason it might not be is if whatever object your binding to the DataGrid (which should be an ObservableCollection or class based on one) does not implement INotifyPropertyChanged, the collection will never know a property change occurred.
If you haven't already, implement INotifyPropertyChanged and raise OnPropertyChanged event for each property. Then, when a value changes, it'll reflect both in the DataGrid and the actual collection being bound.
You'll want to make sure you have an event that updates the database with the new collection values whenever such and such happens (which I noticed button3_Click takes care of).
If this doesn't work, let me know, because it should.
Related
I have two user controls. One is to input data and another one has a combobox that displays data from my MySQL table.
The use types in data in the first user control and presses a button. This adds the data to a MySQL table. I want to add the data immediately / automatically into the combobox (the other user control).
I would prefer not doing it using an event. If it is not possible and I have to use an event, what event should I use? Can it be an event not associated to the button?
Here is the method that reads data from MySQL and adds it to the combobox :
private void LoadFromDatabase()
{
string query = "select name from country";
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand command = new MySqlCommand(query,conn);
MySqlDataReader Read;
conn.Open();
Read = command.ExecuteReader();
while(Read.Read())
{
metroComboBox1.Items.Add(Read.GetString("name"));
}
conn.Close();
}
The current result is that I must reload the windows form to load the new data into thecombobox. Without the reload, the combobox only displays the old data. I have put that method under InitializeComponent(); of the combobox user control.
You can use the event click on the comboBox itself, so whenever you click it to open the dropdown it will update the combobox. Make sure to clear the items at the top of the click event to prevent duplicates.
If you truly insist on having no events, you can use a background worker, however for what you're doing it seems like overkill to spawn a thread just for that.
This is an idea of what the final result should look like.
private void comboBox1_Click(object sender, EventArgs e)
{
if (comboBox1.Items.Count > 0)
comboBox1.Items.Clear();
LoadFromDatabase();
comboBox1.SelectedItem = 0;
comboBox1.Text = "Select Item";
}
So... I have a datagrid that I want to populate with the medication details selected in the combobox. I want to add a new row with the new medication selected from the combobox each time a button is clicked. I am running the below method in a button click event.
private void FillSalesItemGrid()
{
using (SqlConnection con = new SqlConnection(conn))
{
con.Open();
if (!string.IsNullOrEmpty(comboBox_select_Item.Text.ToString()))
{
sqlBuilder.Append("SELECT * FROM Medication WHERE MedName = #medName");
cParameters.Add(new SqlParameter("#medName", comboBox_select_Item.Text.ToString()));
}
SqlCommand cmd = new SqlCommand(sqlBuilder.ToString(), con);
if (cParameters.Count != 0)
{
cmd.Parameters.AddRange(cParameters.ToArray());
}
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("Medication");
da.Fill(dt);
dataGrid_saleItems.ItemsSource = dt.AsDataView();
sqlBuilder.Clear();
cParameters.Clear();
}
At the moment it displays the currently selected combobox item. It doesnt add a new "result" each time the button is clicked. I want it to work as if you were ringing up an item on a POS. Any help will be appreciated.
Instead of creating a new Datatable each time you have to create it once and then fill it up with each function call (SqlDataAdapter.Fill does exactly that).
That way you also only set the itemsource once.
Second solution would be to retrieve the current itemsource, convert it to a DataTable.
Someething like: DataTable table = (dataGrid_saleItems.ItemsSource as DataRowView).toTable()
If you continue with your code that will fill it up aswell.
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!
private void button1_Click(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(ConnectionString)
{
connection.Open();
SqlCommand cmd = new SqlCommand("update dictionary set word=#word", connection);
cmd.Parameters.AddWithValue("#word", wordTextBox.Text);
cmd.ExecuteNonQuery();
this.Close();
}
}
I created a way to take a selected value in a listbox and add the item to a text box on a seperate form. There I am attempting to give the user a way to change that word and have it reflected in the dataset I created. Currently when I change that word it replaces every entry in my dataset with the new word as opposed to just the specific entry. I am trying to figure how to specify just to change that one item.
That is because you are missing a WHERE clause in your query. You need to use a WHERE clause in your query to only update some selected records that you like :
eg : update dictionary set word=#word WHERE ID=#ID.
This is just an example. You have to put the WHERE clause as per your requirement.
Hope this helps.
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