?
Solved

How can I split the Maximum Value of a NumericUpDown Control over several controls?

Posted on 2007-08-03
7
Medium Priority
?
398 Views
Last Modified: 2010-04-14
This is something that, when I first undertook it, I thought would be extremely easy.  Now, I've been working on it for 14 hours straight, I've tried dozens, if not hundreds of different ways to accomplish it, and it's still not working.    I'm about ready to throw my computer at something big and solid.

Ok, now that I'm done ranting (for now), here's my problem.  I have eight NumericUpDown Controls.  Each of these controls has a maximum value of 100.  However, only one control can actually have a value of 100.  (If this is confusing, let me know. It's confusing me as I try to type it.)  All of the controls can have a value of 60, but then there are only 40 points which can be split between the controls.  (i.e. on control's value = 100, and all other controls' values = 60, or two controls = 80, and all other controls = 60, or one control = 65, one control = 70, one control = 75, and five controls = 60 with 10 points left to distribute.)  The maximum value does not have to be met.  I can have 5 controls with a value of 0, and one control with a value of 10 if I want.  

The numberupdown controls names are:  WWlvl, CClvl, GSlvl, BSlvl, BClvl, LClvl, Cooklvl, and Alclvl

The closest I've come to accomplishing this so far has been to have the numericupdowns call the following procedure on the ValueChanged event:

    Private Sub LevelValues()

        Dim MaxValue As Integer = 40

        If GSlvl.Value <= 60 And WWlvl.Value <= 60 And BSlvl.Value <= 60 And Cooklvl.Value <= 60 And Alclvl.Value <= 60 _
        And BClvl.Value <= 60 And LClvl.Value <= 60 And CClvl.Value <= 60 Then

gslvl.

            GSlvl.Maximum = 100
            WWlvl.Maximum = 100
            BSlvl.Maximum = 100
            Cooklvl.Maximum = 100
            Alclvl.Maximum = 100
            BClvl.Maximum = 100
            LClvl.Maximum = 100
            CClvl.Maximum = 100

        Else
            If GSlvl.Value > 60 Then
                WWlvl.Maximum = MaxValue - (100 - GSlvl.Value)
                BClvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
            If WWlvl.Value > 60 Then
                MaxValue = MaxValue - (100 - WWlvl.Value)
                GSlvl.Maximum = 60 + MaxValue
                BClvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
            If BClvl.Value > 60 Then
                MaxValue = MaxValue - (100 - BClvl.Value)
                WWlvl.Maximum = 60 + MaxValue
                GSlvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
            If BSlvl.Value > 60 Then
                MaxValue = MaxValue - (100 - BSlvl.Value)
                WWlvl.Maximum = 60 + MaxValue
                BClvl.Maximum = 60 + MaxValue
                GSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
            If LClvl.Value > 60 Then
                MaxValue = MaxValue - (100 - LClvl.Value)
                'WWlvl.Maximum = 60 + MaxValue
                'BClvl.Maximum = 60 + MaxValue
                'BSlvl.Maximum = 60 + MaxValue
                'GSlvl.Maximum = 60 + MaxValue
                'CClvl.Maximum = 60 + MaxValue
                'Alclvl.Maximum = 60 + MaxValue
                'Cooklvl.Maximum = 60 + MaxValue
            End If
            If CClvl.Value > 60 Then
                MaxValue = MaxValue - (100 - CClvl.Value)
                WWlvl.Maximum = 60 + MaxValue
                BClvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                GSlvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
            If Cooklvl.Value > 60 Then
                MaxValue = MaxValue - (100 - Cooklvl.Value)
                WWlvl.Maximum = 60 + MaxValue
                BClvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                Alclvl.Maximum = 60 + MaxValue
                GSlvl.Maximum = 60 + MaxValue
            End If
            If Alclvl.Value > 60 Then
                MaxValue = MaxValue - (100 - Alclvl.Value)
                WWlvl.Maximum = 60 + MaxValue
                BClvl.Maximum = 60 + MaxValue
                BSlvl.Maximum = 60 + MaxValue
                LClvl.Maximum = 60 + MaxValue
                CClvl.Maximum = 60 + MaxValue
                GSlvl.Maximum = 60 + MaxValue
                Cooklvl.Maximum = 60 + MaxValue
            End If
        End If

End Sub

This sub seems to work ok at first, If I have one control at 100, and change another to 61, the first one drops to 99.  but then it doesn't drop to 98 until the second is at 63, which exceeds the 100 total.

I know there has to be an easier way to do this, and probably with a lot less code.  I'm very open to suggestions right now.

Thank you,
~Skid
0
Comment
Question by:Skidwiz
7 Comments
 
LVL 53

Expert Comment

by:Dhaest
ID: 19623277
I've got some questions:
Is there a maximum value for all controls together ?
Fe: 100 + 60 + 60 + 60 + 60 + 60 = 400
      100 + 80 + 80 + 60 + 40 + 40 = 400
...
0
 
LVL 6

Expert Comment

by:ToFro
ID: 19623314
I'm not 100% sure I understood your goal, but this might just do it(make sure the NumericUpDown Controls have their Maximum set to 100, and their Minimum set to 0:

    Private Const MAX_VALUE As Integer = 520

    Private Sub Counter_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WWlvl.ValueChanged, CClvl.ValueChanged, GSlvl.ValueChanged, BSlvl.ValueChanged, BClvl.ValueChanged, LClvl.ValueChanged, Cooklvl.ValueChanged, Alclvl.ValueChanged

        Dim allocated, available As Integer

        allocated = WWlvl.Value + CClvl.Value + GSlvl.Value + BSlvl.Value + BClvl.Value + LClvl.Value + Cooklvl.Value + Alclvl.Value
        available = MAX_VALUE - allocated

        If allocated >= MAX_VALUE Then
            FreezeCounters()
        Else
            UnfreezeCounters()
        End If

    End Sub

    Private Sub FreezeCounters()
        WWlvl.Maximum = WWlvl.Value
        CClvl.Maximum = CClvl.Value
        GSlvl.Maximum = GSlvl.Value
        BSlvl.Maximum = BSlvl.Value
        BClvl.Maximum = BClvl.Value
        LClvl.Maximum = LClvl.Value
        Cooklvl.Maximum = Cooklvl.Value
        Alclvl.Maximum = Alclvl.Value
    End Sub

    Private Sub UnfreezeCounters()
        WWlvl.Maximum = 100
        CClvl.Maximum = 100
        GSlvl.Maximum = 100
        BSlvl.Maximum = 100
        BClvl.Maximum = 100
        LClvl.Maximum = 100
        Cooklvl.Maximum = 100
        Alclvl.Maximum = 100
    End Sub
0
 
LVL 6

Expert Comment

by:ToFro
ID: 19623349
A couple of notes:

- The MAX_VALUE variable is a constant global integer. I assumed that the maximum allowed sum of all the NumericUpDown Controls was 520.
- I recommend setting the ReadOnly Property of the controls to True(because keyboard input limits need to be handled separately, did the user type in a value which was too big)
- Counter_ValueChanged handles the ValueChanged Event of all the NumericUpDownControls. There is no need to know which one was changed.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 5

Accepted Solution

by:
Bart-De-Bal earned 2000 total points
ID: 19623453
Does this do what you want ?

    Private Sub upd_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WWlvl.ValueChanged, CClvl.ValueChanged, GSlvl.ValueChanged, BSlvl.ValueChanged, BClvl.ValueChanged, LClvl.ValueChanged, Cooklvl.ValueChanged, Alclvl.ValueChanged
        If Not m_blnChanging Then LevelValues(sender)
    End Sub


    Private Sub LevelValues(ByVal sender As System.Windows.Forms.NumericUpDown)
        m_blnChanging = True

        Dim intAbove60 As Integer = 0

        If GSlvl.Value <= 60 And WWlvl.Value <= 60 And BSlvl.Value <= 60 And Cooklvl.Value <= 60 And Alclvl.Value <= 60 _
           And BClvl.Value <= 60 And LClvl.Value <= 60 And CClvl.Value <= 60 Then
            ' Do nothing
        Else
            For Each ctrControl As System.Windows.Forms.Control In Me.Controls
                If TypeOf ctrControl Is System.Windows.Forms.NumericUpDown Then
                    If CType(ctrControl, System.Windows.Forms.NumericUpDown).Value > 60 And ctrControl.Name <> sender.Name Then
                        intAbove60 += CType(ctrControl, System.Windows.Forms.NumericUpDown).Value - 60
                    End If
                End If
            Next

            If sender.Value > 60 Then
                If sender.Value > 100 - intAbove60 Then
                    sender.Value = 100 - intAbove60
                End If
            End If
        End If

        m_blnChanging = False
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        GSlvl.Maximum = 100
        WWlvl.Maximum = 100
        BSlvl.Maximum = 100
        Cooklvl.Maximum = 100
        Alclvl.Maximum = 100
        BClvl.Maximum = 100
        LClvl.Maximum = 100
        CClvl.Maximum = 100
    End Sub
0
 
LVL 1

Author Comment

by:Skidwiz
ID: 19625917
There isn't a maximum value for all controls together.  Each control can equal any number 1-60.  But, above 60, there are only 40 points available to be split among all the controls, are be assigned to just one.  No control can equal more then 100.  

So, using an example, let's say the user clicks the first control, and takes it's value to 60.  At this point all controls still have a max value of 100.  User then takes the second control to 65.  Now, because that control is 5 points over 60, it takes 5 points away from 100.  So, now all other controls' max value is set to 95.  The user then takes the third controls' value to 72.  Now all other controls' max value is 83, because user used 12 more points.  User then takes controls four and five both to 66, using the last 12 available points.  Now, the five controls' values (60, 65, 72, 66, and 66 are set at their maximum values.  However, the last three controls, which are still set at 0, can be adjusted anywhere from 0 - 60, with their max value set at 60.

From here, user decides that the third control (72) is to high, and lowers it to 69.  Now three points just became available for the other 7 controls to use, thereby raising their max value by three.  The control that was 72, and is now 69, doesn't need three points added to it's max, because they are already there.

Does that make it more clear?  I know it's a little confusing, and I'm sorry for it.
0
 
LVL 1

Author Comment

by:Skidwiz
ID: 19626093
Ok, I just looked at that last post, and my math sucks for that example.  ok, user takes first control to 60, which doesn't effect the max value, because it isn't above 60, so all controls still have max of 100.

User takes second control to 65.  This is 5 points above 60, which takes 5 points away from the total 40 points available above 60, making 40 = 35.  So now, each control's max is 95, except for the first one, which still has a max value of 100 (because it also still has those 35 points available, plus the 5 points already used.)  

User takes third control to 75.  This uses 15 points of the max value above 60, taking the 35 down to 20.  So now, the control set to 65 has a max value of 85 (because of it's 5 points used, plus the still available 20 points.), the control set to 75 has a max value of 95 (because of it's 15 used, plus the available 20), and all other controls have a max of 80 (because they haven't used any points yet, and there are 20 of the 40 points still un-used.)  

If the user then lowers the 75 control to 65, 10 points are given back to the max available points above 60, which raises the max of the second control (value of 65) to 95, leaves the third control value at 95, and takes all other controls max from 80 to 90.  

It shouldn't round up or down, because there's 40 points, period.  Not 41, and not 39.  

Once again, sorry about the lousy math in my last post.  I just woke up.
0
 
LVL 1

Author Comment

by:Skidwiz
ID: 19630121
Bart-De-Bal,

I'm sorry, I posted the above comments before I had the opportunity to check the code.  I was just answering the questions from the other posters.  You're code did exactly what I needed.  It's perfect.  Thank you.
0

Featured Post

Free recovery tool for Microsoft Active Directory

Veeam Explorer for Microsoft Active Directory provides fast and reliable object-level recovery for Active Directory from a single-pass, agentless backup or storage snapshot — without the need to restore an entire virtual machine or use third-party tools.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month13 days, 16 hours left to enroll

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question