Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cancel changes made through Databinding?

I'm passing a list of customers via the constructor. Then it's databound to a ListBox. I've also databound a Textbox to allow changing the name of the customer, it automatically update the ListBox and the customer list, which is really nice.

However, I would like the changes not to be maintained if the user click on the Cancel Button. I'm telling the program to set the list of customers to the old one, but it doesn't work, when I open the window again the ListBox show the updated customer names rather than being the old names.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

namespace Bingding_Test
{
    public partial class Form_Customers : Form
    {
        List<Customer> customers;
        List<Customer> old_customers;
        BindingSource bs = new BindingSource();

        public Form_Actors(List<Customer> _customers)
        {
            InitializeComponent();

            customers = _customers;
            old_customers = new List<Customer>(_customers);

            bs.DataSource = customers;
            listBox1.DataSource = bs;
            listBox1.DisplayMember = "Name";

            txtb_name.DataBindings.Add("Text", bs, "Name");
        }

        void Btn_cancelClick(object sender, EventArgs e)
        {
            actors = old_customers;
            this.Close();
        }

        void Btn_saveClick(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Anyone know what I can do to make sure all the changes aren't saved when I click the cancel button?

like image 690
TheScholar Avatar asked Dec 21 '12 01:12

TheScholar


1 Answers

As far as I understood, your question is about making possible to cancel changes made to your List<Customer> through txtb_name. By default, DataBindings automatically applies changes, when validation passed. You can control DataSourceUpdateMode to change this behavior, in different ways, depending on your implementation:

  1. Before you set up any bindings on txtb_name (should be possible with how your code is written):

    txtb_name.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.Never;
    
  2. After you set bindings on txtb_name (also possible with your code):

    foreach( Binding b in txtb_name.DataBindings)
    {
        b.DataSourceUpdateMode = DataSourceUpdateMode.Never;
    }
    
  3. After you set bindings using BindingManagerBase (CurrencyManager or PropertyManager) - more generic approach, because it allows you to handle many controls in one shot, may get useful when your project evolves.

    foreach(Binding b in bindingManager.Bindings)
    {
        b.DataSourceUpdateMode = DataSourceUpdateMode.Never;
    }
    

For complex setups you can use ResumeBinding and SuspendBinding of BindingManagerBase, they can be overriden to provide custom behavior on validation, for example, if multiple fields needs to validated as a whole logical piece, rather than one by one.

Please note that even if you set DataSourceUpdateMode = DataSourceUpdateMode.Never, there will always be one update coming through, according to MSDN (see Remarks section):

Even when the update mode is set to Never, the data source will be updated when the binding is first created, so at that least one update will always occur.

If this is not acceptable for you, i.e. you are building an enterprise-class application with very strict requirements, I suggest handling everything manually - stop using DataBindings.

Credit for the hint at DataSourceUpdateMode goes to Frederik Gheysels for his article about WinForms: DataBinding on a cancellable Dialog Form.

like image 99
Neolisk Avatar answered Oct 19 '22 10:10

Neolisk