DataBinding NumericUpDown to an Object Property

G

Guest

I am having erratic binding from an object properties to a numericUpDown control. Run the code below and it will be erratic in how it binds to the object properties. Sometimes it will work for 10-15 times in a row, then it doesn't. I have tried hooking Click, Validating, Events events to a routine that will access the .Value property of the control as there were some bugs in this(KB#814347).. but I cannot seem to figure this out.

One suggestion was to Implment the IEditableObject (see MyObject2) below but that only seems to add Begin,EndEdit and not sure how that would change this issue.

Any thoughts before I pull out what Little hair I have left..thanks...

//Code that duplicates problem...
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace NumericUpDownBindingToObject
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private MyObject myObject;
public MyObject MyObject
{
get {return myObject;}
set {myObject=value;}
}
private System.Windows.Forms.NumericUpDown numericUpDown1;
private System.Windows.Forms.NumericUpDown numericUpDown2;
private System.Windows.Forms.NumericUpDown numericUpDown3;
private System.Windows.Forms.NumericUpDown numericUpDown4;
private System.Windows.Forms.NumericUpDown numericUpDown5;
private System.Windows.Forms.Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

myObject = new MyObject ();
//myObject = new MyObject2();

SetDataBindings();

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
this.numericUpDown3 = new System.Windows.Forms.NumericUpDown();
this.numericUpDown4 = new System.Windows.Forms.NumericUpDown();
this.numericUpDown5 = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown4)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown5)).BeginInit();
this.SuspendLayout();
//
// numericUpDown1
//
this.numericUpDown1.Location = new System.Drawing.Point(96, 40);
this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.TabIndex = 0;
this.numericUpDown1.Click += new System.EventHandler(this.AValueChanged);
this.numericUpDown1.ValueChanged += new System.EventHandler(this.AValueChanged);
this.numericUpDown1.Leave += new System.EventHandler(this.AValueChanged);
//
// numericUpDown2
//
this.numericUpDown2.Location = new System.Drawing.Point(96, 64);
this.numericUpDown2.Name = "numericUpDown2";
this.numericUpDown2.TabIndex = 1;
this.numericUpDown2.Click += new System.EventHandler(this.AValueChanged);
this.numericUpDown2.ValueChanged += new System.EventHandler(this.AValueChanged);
this.numericUpDown2.Leave += new System.EventHandler(this.AValueChanged);
//
// numericUpDown3
//
this.numericUpDown3.Location = new System.Drawing.Point(96, 88);
this.numericUpDown3.Name = "numericUpDown3";
this.numericUpDown3.TabIndex = 2;
this.numericUpDown3.Click += new System.EventHandler(this.AValueChanged);
this.numericUpDown3.ValueChanged += new System.EventHandler(this.AValueChanged);
this.numericUpDown3.Leave += new System.EventHandler(this.AValueChanged);
//
// numericUpDown4
//
this.numericUpDown4.Location = new System.Drawing.Point(96, 112);
this.numericUpDown4.Name = "numericUpDown4";
this.numericUpDown4.TabIndex = 3;
this.numericUpDown4.Click += new System.EventHandler(this.AValueChanged);
this.numericUpDown4.ValueChanged += new System.EventHandler(this.AValueChanged);
this.numericUpDown4.Leave += new System.EventHandler(this.AValueChanged);
//
// numericUpDown5
//
this.numericUpDown5.Location = new System.Drawing.Point(96, 136);
this.numericUpDown5.Name = "numericUpDown5";
this.numericUpDown5.TabIndex = 4;
this.numericUpDown5.Click += new System.EventHandler(this.AValueChanged);
this.numericUpDown5.ValueChanged += new System.EventHandler(this.AValueChanged);
this.numericUpDown5.Leave += new System.EventHandler(this.AValueChanged);
//
// label1
//
this.label1.Location = new System.Drawing.Point(104, 168);
this.label1.Name = "label1";
this.label1.TabIndex = 5;
this.label1.Text = "label1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.label1);
this.Controls.Add(this.numericUpDown5);
this.Controls.Add(this.numericUpDown4);
this.Controls.Add(this.numericUpDown3);
this.Controls.Add(this.numericUpDown2);
this.Controls.Add(this.numericUpDown1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown4)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown5)).EndInit();
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void SetDataBindings()
{
this.numericUpDown1.DataBindings.Add("Value",myObject,"Amt1");
this.numericUpDown2.DataBindings.Add("Value",myObject,"Amt2");
this.numericUpDown3.DataBindings.Add("Value",myObject,"Amt3");
this.numericUpDown4.DataBindings.Add("Value",myObject,"Amt4");
this.numericUpDown5.DataBindings.Add("Value",myObject,"Amt5");

}
private void AValueChanged(object sender, System.EventArgs e)
{
//Try Forcing Update
if (sender is NumericUpDown)
{
NumericUpDown numericUpDown = sender as NumericUpDown;
Decimal x = numericUpDown.Value;
PropertyManager pm =
numericUpDown.DataBindings["Value"].BindingManagerBase
as PropertyManager;

if (pm != null)
{
pm.EndCurrentEdit();
}

}
this.label1.Text = String.Format(
"{0},{1},{2},{3},{4}"
,MyObject.Amt1
,MyObject.Amt2
,MyObject.Amt3
,MyObject.Amt4
,MyObject.Amt5
);
this.label1.Invalidate();
}
}
public class MyObject
{
private decimal amt1;
public decimal Amt1
{
get {return amt1;}
set {amt1=value;}
}
private decimal amt2;
public decimal Amt2
{
get {return amt2;}
set {amt2=value;}
}
private decimal amt3;
public decimal Amt3
{
get {return amt3;}
set {amt3=value;}
}
private decimal amt4;
public decimal Amt4
{
get {return amt4;}
set {amt4=value;}
}
private decimal amt5;
public decimal Amt5
{
get {return amt5;}
set {amt5=value;}
}
public MyObject()
{
amt1=1.0m;
amt2=2.0m;
amt3=3.0m;
amt4=4.0m;
amt5=5.0m;
}
}
public class MyObject2:MyObject,IEditableObject
{
public MyObject2()
{
}
#region IEditableObject Members

public void EndEdit()
{
// TODO: Add MyObject2.EndEdit implementation
}

public void CancelEdit()
{
// TODO: Add MyObject2.CancelEdit implementation
}

public void BeginEdit()
{
// TODO: Add MyObject2.BeginEdit implementation
}

#endregion

}

}
 
M

Morten Wennevik

Hi Mike,

I think you have too many events interfering with eachother. If you remove the click event the label will update correctly, or at least much better. Might possible remove the Leave event too, as the ValueChanged event should be enough. However, this didn't remove all the "eratics". Typically the first valuechange doesn't appear to be made. Strange thing though. If I set a timer to poll the content of Amt1 continously you can see the value isn't updated. However, if I set a button to show the result, the value gets updated at the moment I hit the button. ??? Furthermore, each time I use the button, clicking on the NumericUpDown will not update the value on the next change, although somehow it will be set. I am baffled. I'm not too familiar with the workings of PropertyManager though, it could be that it holds the value until something happens (in my case, clicking the button).
 
G

Guest

Hi Morten..
Thanks for taking the time to look at this..
All the events were added in this sample to see if accessing the .Value during these events would make a difference. In the actual code I too had figured that just the "Value Changed" event should have been enough and would actually work..Silly me!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top