Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Extend BindingSource with a Dirty property and Dirty changed Event

Extend BindingSource with a Dirty property and Dirty changed Event

Scheduled Pinned Locked Moved C#
databasecsharphelpsql-serverwpf
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    ArjenGroeneveld
    wrote on last edited by
    #1

    Hello, I'm building a database WinForm application. The data objects in my first application where based up on SQLDataConnector, DataSet, DataTables and SQLDataAdapter. Now I moved on and I write Data object classes, which I fill with a SqlDataReader. Modifying the record is done by straight INSERT, UPDATE and DELETE queries written in a Data Object DB Class. The technique is out of the book => Murach's ADO.Net 3.5 LinQ and the Entity Framework. After studying different technique I decided not to go for Entity Framework but hang around with writing my own data classes, making use of binding with data objects and most important ... understanding what happens under the Engine Cowling. So far so GOOD. The client interface works fine, but I like to give the User feedback as soon she/he is changing the content in one of the bounded controls (Textbox, comboBox, ect). In such case I like to show a pencil Icon on the form indicating the content has been changed. So I like to capture an event as soon the record becomes "DIRTY". This way I can decided if an Update is required when the user clicks the button "Save and Close" (just like with leaving a MS Outlook contact form). If the 'IsDirty' property is 'false' the form just should close. Else it should write the changes back to the SQL server in advance of closing. I studied the BindingSource control, but I cannot find an 'IsDirty' property as well no event related to this. I found some articles on the web indicating the same problem. But the code samples are not providing a solution for me. CONCREET: I like to customize the BindingSource by simply adding an "IsDirty" property and an "IsDirtychanged" event. Will this be an easy one???? Your help is most appreciated! With kind regards, Arjen Groeneveld

    L 1 Reply Last reply
    0
    • A ArjenGroeneveld

      Hello, I'm building a database WinForm application. The data objects in my first application where based up on SQLDataConnector, DataSet, DataTables and SQLDataAdapter. Now I moved on and I write Data object classes, which I fill with a SqlDataReader. Modifying the record is done by straight INSERT, UPDATE and DELETE queries written in a Data Object DB Class. The technique is out of the book => Murach's ADO.Net 3.5 LinQ and the Entity Framework. After studying different technique I decided not to go for Entity Framework but hang around with writing my own data classes, making use of binding with data objects and most important ... understanding what happens under the Engine Cowling. So far so GOOD. The client interface works fine, but I like to give the User feedback as soon she/he is changing the content in one of the bounded controls (Textbox, comboBox, ect). In such case I like to show a pencil Icon on the form indicating the content has been changed. So I like to capture an event as soon the record becomes "DIRTY". This way I can decided if an Update is required when the user clicks the button "Save and Close" (just like with leaving a MS Outlook contact form). If the 'IsDirty' property is 'false' the form just should close. Else it should write the changes back to the SQL server in advance of closing. I studied the BindingSource control, but I cannot find an 'IsDirty' property as well no event related to this. I found some articles on the web indicating the same problem. But the code samples are not providing a solution for me. CONCREET: I like to customize the BindingSource by simply adding an "IsDirty" property and an "IsDirtychanged" event. Will this be an easy one???? Your help is most appreciated! With kind regards, Arjen Groeneveld

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      ArjenGroeneveld wrote:

      I studied the BindingSource control, but I cannot find an 'IsDirty' property as well no event related to this.

      The BindingSource has a CurrentItemChanged-event[^] that might be of help.

      ArjenGroeneveld wrote:

      CONCREET: I like to customize the BindingSource by simply adding an "IsDirty" property and an "IsDirtychanged" event. Will this be an easy one????

      Meh, that's an unfair question! It would include subclassing the BindingSource, adding a field, an event, and the wiring for it. You'd also need a testproject, time and documentation - and you can ask additional questions here :)

      I are Troll :suss:

      A 1 Reply Last reply
      0
      • L Lost User

        ArjenGroeneveld wrote:

        I studied the BindingSource control, but I cannot find an 'IsDirty' property as well no event related to this.

        The BindingSource has a CurrentItemChanged-event[^] that might be of help.

        ArjenGroeneveld wrote:

        CONCREET: I like to customize the BindingSource by simply adding an "IsDirty" property and an "IsDirtychanged" event. Will this be an easy one????

        Meh, that's an unfair question! It would include subclassing the BindingSource, adding a field, an event, and the wiring for it. You'd also need a testproject, time and documentation - and you can ask additional questions here :)

        I are Troll :suss:

        A Offline
        A Offline
        ArjenGroeneveld
        wrote on last edited by
        #3

        Okay, Can you help me with the code? Kind regards Arjen

        L 1 Reply Last reply
        0
        • A ArjenGroeneveld

          Okay, Can you help me with the code? Kind regards Arjen

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          ArjenGroeneveld wrote:

          Okay, Can you help me with the code?

          If you want to save the Dirty-field along with the binding, then I'd suggest overriding the Binding class, and not the BindingSource. This might give you a start for a test-form, and having a property in a derived class, using databinding;

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

          namespace Example
          {
          public class MyBinding : Binding
          {
          bool _isDirty;
          public bool IsDirty
          {
          get
          {
          return _isDirty;
          }
          set
          {
          if (_isDirty != value)
          _isDirty = value;
          }
          }

          	public MyBinding(string propertyName, object DataSource, string dataMember)
          		:base(propertyName, DataSource, dataMember)
          	{
          		// more stuff!!
          	}
          }
          
          public class Form1 : System.Windows.Forms.Form 
          {
          	static void Main() 
          	{
          		Application.Run(new Form1());
          	}
          	
          	private TextBox textBox1;
          	private ListBox listBox1;
          	private MyBinding myBinding;
          	
          	public Form1() 
          	{
          		InitializeComponent();
          	}
          
          	private void InitializeComponent()
          	{
          		SuspendLayout();
          		listBox1 = new ListBox();
          		textBox1 = new TextBox();
          
          		textBox1.Location = new Point(16, 68);
          		textBox1.Size = new Size(144, 20);		
          		
          		listBox1.Location = new Point(16, 8);
          		listBox1.Size = new Size(144, 50);
          
          		ClientSize = new Size(176, 100);
          		Controls.Add(textBox1);
          		Controls.Add(listBox1);
          			
          		Name = "Form1";
          		Text = "Form1";
          		Load += new EventHandler(Form1\_Load);
          		ResumeLayout(false);
          	}		
          	
          	private void Form1\_Load(object sender, System.EventArgs e) 
          	{
          		DataTable dt = new DataTable("employee");
          		dt.Columns.Add("firstname");
          		dt.Columns.Add("lastname");
          		dt.Rows.Add("john", "doe");
          		dt.Rows.Add("johnny", "walker");		
          		
          		listBox1.DataSource = dt;
          		listBox1.DisplayMember = "firstname";
          
          		myBinding = new MyBinding("Text", listBox1.DataSource, "lastname");
          		textBox1.DataBindings.Add(myBinding);
          	}
          }
          

          }

          Enjoy :)

          I are Troll :suss:

          A 1 Reply Last reply
          0
          • L Lost User

            ArjenGroeneveld wrote:

            Okay, Can you help me with the code?

            If you want to save the Dirty-field along with the binding, then I'd suggest overriding the Binding class, and not the BindingSource. This might give you a start for a test-form, and having a property in a derived class, using databinding;

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

            namespace Example
            {
            public class MyBinding : Binding
            {
            bool _isDirty;
            public bool IsDirty
            {
            get
            {
            return _isDirty;
            }
            set
            {
            if (_isDirty != value)
            _isDirty = value;
            }
            }

            	public MyBinding(string propertyName, object DataSource, string dataMember)
            		:base(propertyName, DataSource, dataMember)
            	{
            		// more stuff!!
            	}
            }
            
            public class Form1 : System.Windows.Forms.Form 
            {
            	static void Main() 
            	{
            		Application.Run(new Form1());
            	}
            	
            	private TextBox textBox1;
            	private ListBox listBox1;
            	private MyBinding myBinding;
            	
            	public Form1() 
            	{
            		InitializeComponent();
            	}
            
            	private void InitializeComponent()
            	{
            		SuspendLayout();
            		listBox1 = new ListBox();
            		textBox1 = new TextBox();
            
            		textBox1.Location = new Point(16, 68);
            		textBox1.Size = new Size(144, 20);		
            		
            		listBox1.Location = new Point(16, 8);
            		listBox1.Size = new Size(144, 50);
            
            		ClientSize = new Size(176, 100);
            		Controls.Add(textBox1);
            		Controls.Add(listBox1);
            			
            		Name = "Form1";
            		Text = "Form1";
            		Load += new EventHandler(Form1\_Load);
            		ResumeLayout(false);
            	}		
            	
            	private void Form1\_Load(object sender, System.EventArgs e) 
            	{
            		DataTable dt = new DataTable("employee");
            		dt.Columns.Add("firstname");
            		dt.Columns.Add("lastname");
            		dt.Rows.Add("john", "doe");
            		dt.Rows.Add("johnny", "walker");		
            		
            		listBox1.DataSource = dt;
            		listBox1.DisplayMember = "firstname";
            
            		myBinding = new MyBinding("Text", listBox1.DataSource, "lastname");
            		textBox1.DataBindings.Add(myBinding);
            	}
            }
            

            }

            Enjoy :)

            I are Troll :suss:

            A Offline
            A Offline
            ArjenGroeneveld
            wrote on last edited by
            #5

            Hello, The end result I have in mind is an extended BindingSouce control, which is having an "IsDirty" property and an "IsDirtyChange" event. The "IsDirtyChange" should only trigger when the User is making a change in one of the bounded controls. I did some searching in FrameWork and I put the following together, but this code does not trigger when a user changes the content in a control. So something is missing. Extended BindingSource coding... namespace ACMAD.Business { class exBindingSource : BindingSource { // Internal variable private bool flgIsDirty = false; // Event public event EventHandler IsDirtyChanged; protected virtual void OnDirtyChanged(EventArgs e) { if (IsDirtyChanged != null) { IsDirtyChanged(this, e); } } public bool IsDirty { get { return flgIsDirty; } set { flgIsDirty = value; } } protected override void OnBindingComplete(BindingCompleteEventArgs e) { base.OnBindingComplete(e); if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate) { if (!flgIsDirty && (e.BindingCompleteState == BindingCompleteState.Success) && e.Binding.Control.Focused) { flgIsDirty = true; OnDirtyChanged(EventArgs.Empty); } } } protected override void OnCurrentChanged(EventArgs e) { base.OnCurrentChanged(e); if (flgIsDirty == true) flgIsDirty = false; } } } Form coding I placed the exBindingSource on the form and connected an textbox to it. One record is loaded with: // Test purpose exBindingSource1.Clear(); exBindingSource1.Add(ac_Model); And I added an event private void exBindingSource1_IsDirtyChanged(object sender, EventArgs e) { textBox1.Text = exBindingSource1.IsDirty.ToString(); } The idea is that when the user makes a change to Textbox1 that Textbox2 is filled with the exBindingSource1.IsDirty value. But ... nothing happens.. Your help is most appreciated. With kind regards, Arjen Groeneveld

            L S 2 Replies Last reply
            0
            • A ArjenGroeneveld

              Hello, The end result I have in mind is an extended BindingSouce control, which is having an "IsDirty" property and an "IsDirtyChange" event. The "IsDirtyChange" should only trigger when the User is making a change in one of the bounded controls. I did some searching in FrameWork and I put the following together, but this code does not trigger when a user changes the content in a control. So something is missing. Extended BindingSource coding... namespace ACMAD.Business { class exBindingSource : BindingSource { // Internal variable private bool flgIsDirty = false; // Event public event EventHandler IsDirtyChanged; protected virtual void OnDirtyChanged(EventArgs e) { if (IsDirtyChanged != null) { IsDirtyChanged(this, e); } } public bool IsDirty { get { return flgIsDirty; } set { flgIsDirty = value; } } protected override void OnBindingComplete(BindingCompleteEventArgs e) { base.OnBindingComplete(e); if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate) { if (!flgIsDirty && (e.BindingCompleteState == BindingCompleteState.Success) && e.Binding.Control.Focused) { flgIsDirty = true; OnDirtyChanged(EventArgs.Empty); } } } protected override void OnCurrentChanged(EventArgs e) { base.OnCurrentChanged(e); if (flgIsDirty == true) flgIsDirty = false; } } } Form coding I placed the exBindingSource on the form and connected an textbox to it. One record is loaded with: // Test purpose exBindingSource1.Clear(); exBindingSource1.Add(ac_Model); And I added an event private void exBindingSource1_IsDirtyChanged(object sender, EventArgs e) { textBox1.Text = exBindingSource1.IsDirty.ToString(); } The idea is that when the user makes a change to Textbox1 that Textbox2 is filled with the exBindingSource1.IsDirty value. But ... nothing happens.. Your help is most appreciated. With kind regards, Arjen Groeneveld

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I've added a theoretical OnCurrentItemChanged, but my DataGridView won't let me edit the collection. I can't test the code until tomorrow :(

              protected override void OnCurrentItemChanged (System.EventArgs e)
              {
              base.OnCurrentItemChanged (e);
              if (IsDirty == false)
              IsDirty = true;
              }

              I are Troll :suss:

              1 Reply Last reply
              0
              • A ArjenGroeneveld

                Hello, The end result I have in mind is an extended BindingSouce control, which is having an "IsDirty" property and an "IsDirtyChange" event. The "IsDirtyChange" should only trigger when the User is making a change in one of the bounded controls. I did some searching in FrameWork and I put the following together, but this code does not trigger when a user changes the content in a control. So something is missing. Extended BindingSource coding... namespace ACMAD.Business { class exBindingSource : BindingSource { // Internal variable private bool flgIsDirty = false; // Event public event EventHandler IsDirtyChanged; protected virtual void OnDirtyChanged(EventArgs e) { if (IsDirtyChanged != null) { IsDirtyChanged(this, e); } } public bool IsDirty { get { return flgIsDirty; } set { flgIsDirty = value; } } protected override void OnBindingComplete(BindingCompleteEventArgs e) { base.OnBindingComplete(e); if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate) { if (!flgIsDirty && (e.BindingCompleteState == BindingCompleteState.Success) && e.Binding.Control.Focused) { flgIsDirty = true; OnDirtyChanged(EventArgs.Empty); } } } protected override void OnCurrentChanged(EventArgs e) { base.OnCurrentChanged(e); if (flgIsDirty == true) flgIsDirty = false; } } } Form coding I placed the exBindingSource on the form and connected an textbox to it. One record is loaded with: // Test purpose exBindingSource1.Clear(); exBindingSource1.Add(ac_Model); And I added an event private void exBindingSource1_IsDirtyChanged(object sender, EventArgs e) { textBox1.Text = exBindingSource1.IsDirty.ToString(); } The idea is that when the user makes a change to Textbox1 that Textbox2 is filled with the exBindingSource1.IsDirty value. But ... nothing happens.. Your help is most appreciated. With kind regards, Arjen Groeneveld

                S Offline
                S Offline
                sarapkamikazee15
                wrote on last edited by
                #7

                Hi, just want to ask if you solve your question, because right now I'm having problem same as yours, I would be thankful if you can share it, thanks. By the way, what type of your datasource you used in extended bindingDataSource? thank you.. :)

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups