How to Require Confirmation on Form Close When there is Changed Data in a DataGridView

277 views Asked by At

I have simple Form1 with datagridview and I've enabled editing and adding.

Now, when I click on closing form button, and if some of existing cell values are changed or new row has been added I want dialogue box to open (for example, asking me if I want to save changes or don't), and if there is no changes , just to perform simple form closing.

How can I accomplish this ?

Ok, here is what I've got so far. I'm trying to this one using CSLA framework, I've created root editable collection public class PDVCollection : BusinessBindingListBase<PDVCollection, PDV> and editable child public class PDV : BusinessBase<PDV> On Form1 I've got this code

  public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();

    }


    public PDVCollection s;
    private void Form1_Load(object sender, EventArgs e)
    {
        bindingSource1.DataSource = PDVCollection.GetAll();

    }

    private void toolStripButton1_Click(object sender, EventArgs e)
    {
        s = (PDVCollection)bindingSource1.DataSource;

        s = s.Save();
        bindingSource1.DataSource = s;


    }



    private void toolStripButton3_Click(object sender, EventArgs e)
    {


        if (dataGridView1.CurrentCell.RowIndex > -1)
        {

            PDV sel = (PDV)dataGridView1.CurrentRow.DataBoundItem;

            s = (PDVCollection)bindingSource1.DataSource;
            s.Remove(sel);
            s = s.Save();
        }

    }

i want to cut s = s.Save(); from both toolStripButton1_Click and toolStripButton3_Click and If something is changed/added/deleted and I perform closing event

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (//some code to implement)
        {
            DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                s = (PDVCollection)bindingSource1.DataSource;
                s = s.Save();
            }
            else if (dialogResult == DialogResult.No)
            {
                this.DialogResult = DialogResult.OK;
            }
        }
    }
3

There are 3 answers

1
AngularRat On BEST ANSWER

If you're doing databinding to a DataSource, then you can use the datasource to determine whether it has been changed in the FormClosing or FormClosed event. The actual implementation would be up to the type of datasource you are using.

If you're not specifying a datasource, then the data by default can be accessed in the Rows collection of the DataGrid. That collection class doesn't have a "changed" flag by default, but it DOES have a CollectionChanged event that you could hook up.

So, in your form's construtor, you could do a

DataGrid1.CollectionChanged += Rows_CollectionChanged;

And then in your Rows_CollectionChanged you could set a flag that data has changed and needs to be saved. Obviously giving much more detail would require knowing more about the details of your datagrid and datasource.

Per the comments below, you may want more than a flag depending on how you define "changed". If you need to know that a field was changed, then changed back to the original value then as a commenter below says a simple flag wouldn't do it, and you might need to store a shadow copy of the original data.

That said, if you need to handle really complicated undo scenarios you're going to want datasource designed for that, which is a whole different topic.

EDIT: If you're using CSLA objects as your data source, then there should be an IsDirty flag on the objects. So just iterate over the items in the datasource on the FormClosed event and check the IsDirty flag for each object.

0
Hank Mooody On

Ok, here is final working solution, if anyone is looking for it.

public Form1()
    {
        InitializeComponent();

    }


    public PDVCollection s;
    private void Form1_Load(object sender, EventArgs e)
    {
        bindingSource1.DataSource = PDVCollection.GetAll();
        s = (StopaPDVCollection)bindingSource1.DataSource;
    }


    private void toolStripButton1_Click(object sender, EventArgs e)

        s = s.Save();
        bindingSource1.DataSource = s;


    }


    private void toolStripButton3_Click(object sender, EventArgs e)
    {


        if (dataGridView1.CurrentCell.RowIndex > -1)
        {

            PDV sel = (PDV)dataGridView1.CurrentRow.DataBoundItem;

            s.Remove(sel);

        }

    }



    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (s.IsDirty)
        {
            DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", "Poruka", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                s = (PDVCollection)bindingSource1.DataSource;

                s = s.Save();
                bindingSource1.DataSource = s;
            }
            else if (dialogResult == DialogResult.No)
            {
                this.DialogResult = DialogResult.OK;
            }
        }

    }

}
1
Sagar Upadhyay On

You need to create flag variable and initially set it to false

 bool isAnythingChange = false;

And make this variable to true on new row add, or value change event. For sample I have shown below

 void txt_Change(object sender, EventArgs e)
 {
      isAnythingChange = true;
 }

And while you are handling form closing event make point to check isAnythingChange. If it's value is true then ask for confirmation or else close form without confirmation.

EDIT: As you maintain in your question, updated code may be like this.

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (isAnythingChange)
        {
            DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                s = (PDVCollection)bindingSource1.DataSource;
                s = s.Save();
            }
            else if (dialogResult == DialogResult.No)
            {
                this.DialogResult = DialogResult.OK;
            }
        }
    }