Reputation: 466
I have a list of items that have a name, price and quantity value. This list is stored in one form, and this form also had an edit button, so that when a user clicks on a row, they are able to edit this item inside another form that pops up.
I have my code working so that the item changes in the list, however it seems like the DataGridView just isn't updating when the list is changed. When I edit an item, and add in a new row, it shows the changed values.
Here is my code for my first form:
private void EditButton_Click(object sender, EventArgs e)
{
EditForm editForm = new EditForm();
if (BasketGrid.RowCount > 0)
{
editForm.Show();
}
}
So this juts sets up the button so that it shows the other form. "BasketGrid" is my DataGridView, that is also given a public initialization at the beginning of my code (Called dgv)
public void EditOkBut_Click(object sender, EventArgs e)
{
this.newName = editNameBox.Text;
decimal price;
int quant;
if (decimal.TryParse(editPriceBox.Text, out price))
{
this.newPrice = price;
}
else
{
MessageBox.Show("Incorrect format for price");
}
if(int.TryParse(editQuantBox.Text, out quant))
{
this.newQuantity = quant;
}
else
{
MessageBox.Show("Incorrect format for quantity");
}
foreach (OrderItem o in basketForm.GetList().ToList())
{
string listName = basketForm.getListName();
if (listName == o.ProductName)
{
o.ProductName = this.newName;
o.ProductPrice = this.newPrice;
o.ProductQuantity = this.newQuantity;
}
}
this.Close();
}
This is my "Edit Button" in my secondary form. This grabs my itemlist from my other form via a method, and compares the product name in of the orderitem in the list, and the listname that the user has selected from the row.
I'd created 'basketForm' as a new object of my other form, so I can access methods and stuff. I've tried to use basketForm.dgv.Refresh(); but to no avail.
Any help is appreciated.
Cheers, Daniel
Upvotes: 0
Views: 61
Reputation: 14231
You should implement INotifyPropertyChanged interface in the OrderItem
class. This will update only one value in DataGridView
, instead of updating the entire collection, which may be critical if the collection is very large and its binding may trigger actions, like validation, etc.
class OrderItem : INotifyPropertyChanged
{
private string name;
// other fields : price, quantity
public string Name
{
get { return name; }
set
{
if (value != name)
{
name = value;
NotifyPropertyChanged();
}
}
}
// other properties: Price, Quantity
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Also you have to use BindingList class instead of List
. It supports two-way data-binding mechanism.
Upvotes: 0
Reputation: 721
You can use BindingSource and ShowDialog...
Example:
public partial class MainForm : Form
{
private BindingSource bindingSource = new BindingSource();
List<YourData> yourData = new List<YourData>();
public MainForm()
{
InitializeComponent();
bindingSource.DataSource = yourData;
dgv.DataSource = bindingSource;
}
}
Changes will be reflected to your grid like this...
private void EditButton_Click(object sender, EventArgs e)
{
EditForm editForm = new EditForm(yourData);
if (BasketGrid.RowCount > 0)
{
editForm.ShowDialog(this);
bindingSource.ResetBindings(true);
}
}
//Change your Data in EditForm whatever you want
public partial class EditForm : Form
{
List<YourData> yourData;
public EditForm(List<YourData> yourData)
{
InitializeComponent();
this.yourData = yourData;
}
}
Upvotes: 1