views:

301

answers:

3

I running into an infinite loop problem.

I have two numeric up/down controls (Height and Width input parameters). When the user changes the value of one of the controls, I need to scale the other to keep a height to width ratio constant.

Is there a way to set the value of a control without invoking a ValueChanged Event. I only want the ValueChanged event to execute when the user changes the value.

private void FloorLength_ValueChanged(object sender, EventArgs e)
{
    if (this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap != null)
    {
        FloorWidth.Value = FloorLength.Value * 
            ((decimal)this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap.Height / 
            (decimal)this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap.Width);
    }
}

private void FloorWidth_ValueChanged(object sender, EventArgs e)
{
    if (this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap != null)
    {
        FloorLength.Value = FloorWidth.Value * 
            ((decimal)this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap.Width / 
            (decimal)this.mCurrentDocument.System.SuperTrakSystem.FloorBitmap.Height);
    }
}
+1  A: 

I'm not that familiar with the NumericUpDown control, but there may not be a way to set the value without triggering the ValueChanged event. Instead, before you set the value, you could set a flag indicating that the event should be ignored, and clear the flag after setting the value. In your event handler, do nothing if the flag is set.

private bool ignoreEvent = false;
private void setValue(int value)
{
    ignoreEvent = true;
    FloorLength.Value = value;
    ignoreEvent = false;
}

private void FloorLength_ValueChanged(object sender, EventArgs e)
{
    if(ignoreEvent) { return; }

    // your code here
}
CodeSavvyGeek
A: 

In theory, these values should stabilize... Meaning if the user changes 1, the system changes the other and then the first one remains the same. Therefore, I would just add a check into both of the event handlers (pseudocode):

newValue = equation;
if(controlValue != newValue)  
{
    controlValue = newValue; //raises the event only when necessary.
}
Jacob G
they don't stabilize, I think it's because the values get rounded to two decimal places
Kevin
So, can we get some more info about the values (an example or two) and the NumericUpDown properties (e.g. DecimalPlaces)?
Jacob G
A: 

Thanks for your answers.

I came up with an alternate solution that works. User changing the value from the UI triggers the event, while programmatic Value parameter changes do not trigger the event.

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

namespace myNameSpace.Forms.UserControls
{
    public class NumericUpDownSafe : NumericUpDown
    {
        private bool bypassEvent = false;
        EventHandler eventHandler = null;

        public event EventHandler ValueChanged
        {
            add
            {
                eventHandler += value;
                base.ValueChanged += value;
            }

            remove
            {
                eventHandler -= value;
                base.ValueChanged -= value;
            }
        }

        public decimal Value
        {
            get
            {
                return base.Value;
            }
            set
            {
                base.ValueChanged -= eventHandler;
                base.Value = value;
                base.ValueChanged += eventHandler;
            }
        }
    }
}
Kevin