Reputation: 3
I'm trying to Count up and delete the duplicates rows when a new row is added, and if the row does not exist it should make a new row for it. If a new row is added and is the same as one of the existing ones is would add it to the count.
It should look for if: 'Code' is the same and if the 'Part' is the same.
What I'm getting:
Updated code now: CodeCombox has been replaced with textBoxScanner.
private void addcodes()
{
if (!int.TryParse(CountTextBox.Text, out var count)) return;
var product = _bindingList
.FirstOrDefault(prod =>
prod.Code == Convert.ToString(textBoxScanner.Text) &&
prod.Parts == PartsComboBox.Text);
if (product == null)
{
_bindingList.Add(new Product()
{
Code = Convert.ToString(textBoxScanner.Text),
Parts = PartsComboBox.Text,
Count = count
});
}
else
{
product.Count = product.Count + count;
}
textBoxScanner.Focus();
textBoxScanner.Clear();
}
Class has been updated to a string:
public class Product : INotifyPropertyChanged
{
private string _code;
private string _parts;
private int _count;
public string Code
{
get => _code;
set
{
_code = value;
OnPropertyChanged();
}
}
public string Parts
{
get => _parts;
set
{
_parts = value;
OnPropertyChanged();
}
}
public int Count
{
get => _count;
set
{
_count = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 0
Views: 450
Reputation: 5127
One solution is to use a BindingList with a concrete class rather than work directly from the DataGridView. In the following sample there are two ComboBox controls for Code and Parts, a TextBox for Count.
Class to store information
public class Product : INotifyPropertyChanged
{
private int _code;
private string _parts;
private int _count;
public int Code
{
get => _code;
set
{
_code = value;
OnPropertyChanged();
}
}
public string Parts
{
get => _parts;
set
{
_parts = value;
OnPropertyChanged();
}
}
public int Count
{
get => _count;
set
{
_count = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In the add button lambda determines if a Product exists, if yes, add count, if no add new record. Note there is a current button if you need to inspect or change the current row in the DataGridView.
public partial class Form1 : Form
{
private readonly BindingList<Product> _bindingList;
public Form1()
{
InitializeComponent();
_bindingList = new BindingList<Product>();
dataGridView1.DataSource = _bindingList;
dataGridView1.AllowUserToAddRows = false;
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
Controls
.OfType<ComboBox>()
.ToList()
.ForEach(cb => cb.SelectedIndex = 0);
}
private void AddButton_Click(object sender, EventArgs e)
{
if (!int.TryParse(CountTextBox.Text, out var count)) return;
var product = _bindingList
.FirstOrDefault(prod =>
prod.Code == Convert.ToInt32(CodeComboBox.Text) &&
prod.Parts == PartsComboBox.Text);
if (product == null)
{
_bindingList.Add(new Product()
{
Code = Convert.ToInt32(CodeComboBox.Text),
Parts = PartsComboBox.Text,
Count = count
});
}
else
{
product.Count = product.Count + count;
}
}
private void CurrentButton_Click(object sender, EventArgs e)
{
if (_bindingList.Count >0 && dataGridView1.CurrentRow != null)
{
var product = _bindingList[dataGridView1.CurrentRow.Index];
MessageBox.Show($"{product.Code}\n{product.Parts}\n{product.Count}");
}
else
{
// no current row
}
}
}
Upvotes: 1