Mikhail Danshin
Mikhail Danshin

Reputation: 393

How to save dataGridView changed data?

I'm try to create database application and implement MVP pattern. I'm using EF+CodeFirst. There is View, Presenter and Model.

View have dataGridView and SetData() method.

public void SetData(IEnumerable<Goods> items)
{
    dataGridView1.DataSource = items.ToList();
}

Presenter retrieve data from Model and call SetData() of View.

internal void Select()
{
    var data = _modelGoods.Select();
    _view.SetData(data);
}

But, how to save a changed cell data?

Upvotes: 0

Views: 3769

Answers (3)

Reza Aghaei
Reza Aghaei

Reputation: 125187

If you are working with connected entities, the job is simple, you can load data in context and then bind data to the grid and manipulate data and at last call SaveChanges of the context that you loaded data, to apply changes to database.

If you are working with disconnected entities, you should track entity changes. Some of your entities are added, some of them are changed and some of them are deleted. And you want to insert those added entities and update those changed entities and delete those deleted entities from context. To do so you can inherit from a BindigList<T> or an ObservableCOllection<T> or use a BindingSource and listen to list changes events and track changes and store changes in 3 separated lists (added, changed, deleted) and then pass these lists to the server to apply changes.

Sample for Connected Entities:

SampleDbContext db;
private void Form1_Load(object sender, EventArgs e)
{
    db = new SampleDbContext();
    db.Products.Load();
    this.productDataGridView.DataSource = db.Products.Local.ToBindingList();
}
private void SaveButton_Click(object sender, EventArgs e)
{
    this.productDataGridView.EndEdit();
    db.SaveChanges();
}

Sample for Disconnected Entities:

I suppose you have tracked changes using BindingSource or BindingList<T> or ObservableCollection<T> or even using DataGridView events or something else. Now you should have added, edited and deleted entities and you can pass them to your server code to apply changes this way:

public void SaveChanges(List<Product> added, List<Product> edited, List<Product> deleted)
{
    using (var db = new SampleDbContext())
    {
        foreach (var entity in deleted)
        {
            if (edited.Contains(entity))
                edited.Remove(entity);

            if (added.Contains(entity))
                added.Remove(entity);
            else
                db.Entry(entity).State = EntityState.Deleted;
        }

        foreach (var entity in added)
        {
            if (edited.Contains(entity))
                edited.Remove(entity);
            db.Entry(entity).State = EntityState.Added;
        }

        foreach (var entity in edited)
            db.Entry(entity).State = EntityState.Modified;

        db.SaveChanges();
    }
}

Upvotes: 2

Fabio
Fabio

Reputation: 32445

I am not a expert of MVP pattern, if based on the examples view know about model,
then you can use DataGridView.CellEndEdit eventhandler

private void dgvtest1_CellEndEdit(Object sender, DataGridViewCellEventArgs e)
{
    if(e.RowIndex < 0)
        return;
    if(e.ColumnIndex < 0)
        return;
    DataGridView dgv = (DataGridView)sender;
    DataGridViewRow row = dgv.Rows(e.RowIndex);
    Good model = row.DataBoundItem as Good
    if(model == null)
        return;
    //Then decide which property was changed and update it
    String boundPropertyName= dgv.Columns(e.ColumnIndex).DataPropertyName;
    if(boundPropertyName.Equals(nameOf(model.SomeProperty)) == true)
    {
        //Update value
        return;
    }
    //.. other columns
}

Upvotes: 0

Shyju
Shyju

Reputation: 218702

Typically, to update a record using EF, you read the entity object first, update the property values with the new values, the save it back.

Something like this.

var idOfRecord=12;
using(var yourDbContext=new YourDbContext())
{
  var good=yourDbContext.Goods.FirstOrDefault(s=>s.Id==idOfRecord);
  if(good!=null)
  {
    good.Name = "New name read from UI"; //Updating the Name property value
    yourDbContext.Entry(good).State = EntityState.Modified;
    yourDbContext.SaveChanges();
  }
}

Assuming YourDbContext is the name of your DbContext class. Update the property/class names as needed to match your use case.

Upvotes: 1

Related Questions