I am currently working on a C# Winforms application with Entity Framework 5.
My problem is how to do a delete (which only tag isDeleted
field as true
) to an item on the bindingsource
binded to an entity
.
This is a screenshot of my form:
The DataGridView
is bound to enrollmedsBindingSource
. See this code of form load which fills the binding source:
private void EnrollMedicationFrm_Load(object sender, EventArgs e)
{
context.enrollmeds.Where(adm => adm.FK_Admission == _SelectedPKAdm && adm.isDeleted == false).ToList();
enrollmedsBindingSource.DataSource = context.enrollmeds.Local;
}
As you can see on the above code, I filtered the data to display only the data which isDeleted
is set to false.
Below is the code for my delete button:
private void DeleteBtn_Click(object sender, EventArgs e)
{
if (enrollmedsDataGridView.CurrentRow == null)
{
MessageBox.Show("No item selected.", "System Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
enrollmedsBindingSource.Remove(enrollmedsBindingSource.Current);
}
}
This code removes the item from the database if I call context.SaveChanges();
on save button.
Below is the code for save button:
private void SaveBtn_Click(object sender, EventArgs e)
{
this.enrollmedsBindingSource.EndEdit();
context.enrollmeds.Local
.Where(a => a.C__PK_EnrollMeds == 0)
.ToList().ForEach(i =>
{
i.FK_DC_Patient = pxdetails.pxDC.PK_Datacenter;
i.FK_DC_userAdd = mainfrm.PK_DC_UserLoggedIn;
i.AddDateTime = currdatetime;
i.FK_Admission = pxdetails.adm.PK_Admission;
});
this.context.SaveChanges();
enrollmedsDataGridView.Refresh();
this.Dispose();
}
What I want to do, is to remove the entry on the DataGridView
(from user's view) but only tag the isDeleted
field is true
in the database (for audit purposes).
Note:
The save button only clicked once the user is done on all the changes, so the form need to capture what is deleted (isDeleted
), changed, and added upon saving.
You should set IsDeleted
property of your entity to true
and the call SaveChanges
. For example, if you have a Product
entity:
var p = (Product)bindingSource.Current;
p.IsDeleted = true;
db.SaveChanges();
Then if you are not going to reload data, you can remove the item from list to not show it:
bs.RemoveCurrent();
db.Entry(p).State = EntityState.Detached;
Or you can reload data:
db.Products.Where(x => x.IsDeleted == false).Load();
bindingSource.DataSource = db.Products.Local;
Note
If you are not going to save changes immediately, you need to do something else after setting IsDeletet
to true
:
You can stop working connected to context and use a BindingList<T>
or ObservableCollection<T>
for data-binding and track data changes yourself. Then you can simply have a list of deleted items to set their IsDeleted
property to true
when saving changes.
As another option, after setting IsDeleetd
to true, you can change the appearance of deleted rows in DataGridView
. For example, you can handle RowPostPaint
event of DataGridView
and draw a red strikeout like over the row.