Thread: Limited response to NumericUpDown updates

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    5

    Limited response to NumericUpDown updates

    Hello. I am having trouble with the NumericUpDown control in a program I am writing. On the ValueChanged event, the program performs a somewhat processor intensive operation, so that when the control is changed rapidly (e.g. by scrolling), the operation occurs several times in succession and the program is slowed considerably. However, it is only necessary that the operation be completed for the final value.

    Is there any way I can get the control to ignore changes to its value if the value changes again in a very short time span? I attempted to use separate threads that were created when the value changed, waited a few milliseconds, and then carried out the operation if the value had remained constant, but as you can probably imagine this method was finicky at best and seemed unnecessarily messy regardless.

    I've been trying to solve this problem for some time, so any assistance would be greatly appreciated.

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    How about this? Seems to work in my simple tests:
    Code:
        public partial class Form1 : Form
        {
            private System.Timers.Timer _Timer;
    
            public Form1()
            {
                InitializeComponent();
    
                _Timer = new System.Timers.Timer() { AutoReset = false, Interval = 2000 };
                _Timer.Elapsed += new System.Timers.ElapsedEventHandler(_Timer_Elapsed);
            }
    
            private void _Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                // Do processor-intensive operation here
            }
    
            private void numericUpDown1_ValueChanged(object sender, EventArgs e)
            {
                _Timer.Stop();
                _Timer.Start();
            }
        }
    I have it waiting 2 seconds, but you can set Interval to whatever you feel is appropriate.
    Last edited by itsme86; 11-07-2010 at 04:46 PM.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Posts
    5
    Wonderful -- works like a charm. Thank you.

  4. #4
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Have you thought about using the Validated or the LostFocus event instead of ValueChanged?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  5. #5
    Registered User
    Join Date
    Nov 2010
    Posts
    5
    The behavior of those events doesn't feel right in context. Thank you for the suggestions, however.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by roconnell View Post
    The behavior of those events doesn't feel right in context. Thank you for the suggestions, however.
    I think LostFocus is much closer than ValueChanged... When I design dialogs they typically don't do anything on their own (besides validation), just return a delegate which does the corresponding calculation at the caller's behest.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Quote Originally Posted by brewbuck View Post
    I think LostFocus is much closer than ValueChanged.
    I agree. If you want to do something every time the value changes, use ValueChanged. If you want to do something with the final value, use LostFocus or Validated (if you've turned on validation for that control).

    After thinking about it, I sort of like the use of a Timer here. It allows the user to keep focus on the spinner and still raise the desired event. Still, it feels like a hackish way to write a UI.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  8. #8
    Registered User
    Join Date
    Nov 2010
    Posts
    5
    Perhaps I should explain further. The program is (partly) a tile editor for a game, and the spinner is used to select the index of the tileset to be used to draw the current screen. When its value is changed, the image which contains the tileset has to be divided up before it can be used -- this is the "processor intensive operation." For one tileset, it takes a fraction of a second to do this, but this quickly adds up if it tries to do it for each tileset unnecessarily. It doesn't simply complete the operation for each tileset ahead of time because there are so many tilesets that this would use several hundred megabytes of memory.

    The user will expect the tileset to be changed instantly if they, for example, just push the up or down arrow once or twice. This is why I do not want it to have to lose focus to change. Part of it is that I am replicating much of the functionality of the editor that comes with the game, which acts in this way, but does not have the advantage of allowing the user to type in a number if they know which one they want.

    I agree that it seems hackish, but it works exactly how I want it to, and if there is no better solution, I am going to stick to it.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Sounds like your approach is incorrect. Load certain tilesets into memory and partition them so they are setup as single images. Alternatively you can load all tilesets into memory, split the up into tiles, and write the results to disk and flush the memory. Your application can then use these temporary tile sets at runtime and remove them when the app is closed. You can also use a most recently used list.

    1. Only load what has been requested
    2. If an image is requested move it to the top of the most recently used list
    3. If the list is over some specified limit lop off the bottom of it until the list is back within limits or lop off the heavy hitters at the bottom of the list. The bottom of the list represents the least recently used images so these images can be removed.

    This is a simple on-demand load system that uses an MRU list as its cache.
    Last edited by VirtualAce; 11-10-2010 at 09:45 PM.

  10. #10
    Registered User
    Join Date
    Nov 2010
    Posts
    5
    I have considered caching the tiles as individual images, and I may revisit this issue and implement such a system in the future. However, at the moment, I am more focused on other sections of the application.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. ISAPI Filter Code
    By bfreshour in forum C++ Programming
    Replies: 1
    Last Post: 03-11-2010, 06:48 AM
  2. what is an elegant way to transform request to response?
    By kypronite in forum Networking/Device Communication
    Replies: 1
    Last Post: 12-24-2008, 10:47 AM
  3. Sorting out cause of wrong response from class members
    By imCrushedByCode in forum C++ Programming
    Replies: 11
    Last Post: 04-18-2006, 12:30 AM
  4. Critical Updates.
    By anonytmouse in forum Tech Board
    Replies: 4
    Last Post: 09-30-2003, 07:50 AM
  5. Array, reading in response etc...
    By mattz in forum C Programming
    Replies: 4
    Last Post: 12-05-2001, 11:41 AM