Search code examples
c#user-controlsevent-handling

C# set UserControl.Value without invoking the ValueChanged event


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);
    }
}

Solution

  • 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.Windows.Forms;
    
    namespace myNameSpace.Forms.UserControls
    {
        public class NumericUpDownSafe : NumericUpDown
        {
            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;
                }
            }
        }
    }