Issue setting .maximum on a scrollbar

Unimatrix_001
Unimatrix_001 used Ask the Experts™
on
Hello,

I'm trying to get this scrollbar thing working correctly so that when I scroll I actually get the full maximum range - I am calculating the maximum as shown, but the valueChanged event gives me a limiting value.

Where am I going wrong?

Thanks,
Uni
vScrollBar1.Minimum=0;
vScrollBar1.Maximum=0;

if(flowLayoutPanel1.Size.Height>panel1.Size.Height){
	vScrollBar1.Maximum=(flowLayoutPanel1.Size.Height-panel1.Size.Height)+(vScrollBar1.LargeChange-1);
	listBox1.Items.Insert(0, "Diff: "+(flowLayoutPanel1.Size.Height-panel1.Size.Height).ToString()+ " LC: " + vScrollBar1.LargeChange.ToString()+ " " + vScrollBar1.Maximum.ToString()+ " " + "Max: "+vScrollBar1.Maximum.ToString());
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
im not sure why you need to calculate scroll bars. on your flow layout panel turn AutoScrol proporty to true and if scrolling is required on any machine they will be there.

Author

Commented:
I'm creating my own scrollbars, the flow panel is there just for testing...
vScrollBar1 = can you past the code here
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Author

Commented:
As requested...
In FMain.Designer.cs
			this.vScrollBar1.Location = new System.Drawing.Point(487, 22);
			this.vScrollBar1.Name = "vScrollBar1";
			this.vScrollBar1.Size = new System.Drawing.Size(26, 341);
			this.vScrollBar1.TabIndex = 1;
			this.vScrollBar1.ValueChanged += new System.EventHandler(this.vScrollBar1_ValueChanged);
			this.vScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler(this.vScrollBar1_Scroll);



In FMain.cs:
		private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e){
			vScrollBar1.Minimum=0;
			vScrollBar1.Maximum=0;
			if(flowLayoutPanel1.Size.Height>panel1.Size.Height){
				vScrollBar1.Maximum=(flowLayoutPanel1.Size.Height-panel1.Size.Height)+(vScrollBar1.LargeChange-1);
				listBox1.Items.Insert(0, "Diff: "+(flowLayoutPanel1.Size.Height-panel1.Size.Height).ToString()+ " LC: " + vScrollBar1.LargeChange.ToString()+ " " + vScrollBar1.Maximum.ToString()+ " " + "Max: "+vScrollBar1.Maximum.ToString());
			}
		}

		private void vScrollBar1_Scroll(object sender, ScrollEventArgs e) {
			//if(e.OldValue>e.NewValue)
			//flowLayoutPanel1.Top=-e.NewValue;
		}

		private void vScrollBar1_ValueChanged(object sender, EventArgs e) {
			//listBox1.Items.Insert(0, vScrollBar1.Value.ToString());
			//listBox1.Items.Insert(0, "Unshown: " + vScrollBar1.Maximum.ToString());
			flowLayoutPanel1.Top=-vScrollBar1.Value;
		}

Open in new window

Commented:
I don't understand what's your problem. It looks working for me. Can you post a screenshot and indicate what is not working?

Author

Commented:
Hi magicdlf,

Give me a couple of mins and I'll upload the project...

Commented:
Change this line:
                        vScrollBar1.Maximum=(flowLayoutPanel1.Size.Height-panel1.Size.Height)+(vScrollBar1.LargeChange-1);
to:
                vScrollBar1.Maximum = (flowLayoutPanel1.Size.Height - panel1.Size.Height) + (15-1);
The vScrollBar1.LargeChange becomes 1 after you setting:
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = 0;

Author

Commented:
Hrm,

Well, it seems to be much better - a couple of pixels off though... But where does that 15 come from?

Thanks,
Uni

Commented:
It's just pixels. Do not use LargeChange here and everything would be OK.

Author

Commented:
Here's the project...
SampleProject.zip

Author

Commented:
I have to use LargeChange though unless I set it to 1, which makes the scrollbar increments absolutely massive... See the LargeChange property shown on MSDN:

http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.largechange.aspx

Specifically states that calculating the maximum should take into account LargeChange, and although I've tried their formula it's just not working correctly. :(

Commented:
Look at mine~ Surprisingly quite similar as yours. ;)

Author

Commented:
The sample project doesn't use LargeChange, but it should... That's my issue as I don't want to make LargeChange=1.

Thanks,
Uni

Author

Commented:
Hi there,

Ok I see - but LargeChage is 15, which is the magic number you use, but when you swap 15 for LargeChange it stops working?

Thanks,
Uni

Commented:
That is because:
The vScrollBar1.LargeChange becomes 1 after you setting:
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = 0;

Author

Commented:
Why is this?

Commented:
I need to check it on MSDN later~  I found that it's interesting that your have several typo in your sample project:
private void panel1_Layout(object sender, LayoutEventArgs e) {   // should be flowLayoutPanel_Layout
flowLayoutPanel1.Top-=vScrollBar1.Value;   // should be flowLayoutPanel1.Top=-vScrollBar1.Value;

So now is your project working with the code change?

Author

Commented:
Actually, I've just tested the following with the ProgressBarUpdate and it seems LargeChange remains constant, check the value changed for the listbox item add it's the same as when it started to expand.. 15. :S

Thanks,
Uni

Author

Commented:
After all that - forgot to add it...
ProgressBarUpdate.zip

Commented:
So is that working? What's the problem now?

Author

Commented:
No, I've got the original problem. When I use the LargeChange I don't get the correct increments.

Author

Commented:
Here's the project - I've updated it with the MS LargeChange algorithm, which isn't working too well:

http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.largechange.aspx

Also, you'll notice the panel starts off with the top not aligned to the top of the frame, this is quite strange. Also, on the 14th add - i.e. the button which is the first to be off the panel - the scrollbars don't update.

Thanks,
Uni
ProgressBarUpdate.zip
try:
vScrollBar1.Maximum = Math.Abs(panel1.Size.Height - flowLayoutPanel1.Size.Height) + vScrollBar1.LargeChange;

Open in new window

Commented:
Try this:
        private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e)
        {
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = vScrollBar1.LargeChange;
            if (flowLayoutPanel1.Size.Height > panel1.Size.Height)
            {
                vScrollBar1.Maximum = (flowLayoutPanel1.Size.Height - panel1.Size.Height) + (vScrollBar1.LargeChange - 1);
                listBox1.Items.Insert(0, "Diff: " + (flowLayoutPanel1.Size.Height - panel1.Size.Height).ToString() + " LC: " + vScrollBar1.LargeChange.ToString() + " " + vScrollBar1.Maximum.ToString() + " " + "Max: " + vScrollBar1.Maximum.ToString());
            }
        }

The flowLayoutPanel doesn't change the layout whil the "14th add". That's why the scroll bar didn't update.

Author

Commented:
zadeveloper:
Sorry, I'm afraid that messes up the maximum value.

magicdlf:
>>The flowLayoutPanel doesn't change the layout whil the "14th add". That's why the scroll bar didn't
>>update.
The layout event is raised everytime the layout needs to be reworked, so it is bound to even on the 14th add, if it didn't I'd have bigger problems???

Commented:
That's true: The layout event is raised everytime the layout needs to be reworked
what's the case of the 14th add? I think I misunderstood your statement

Author

Commented:
Well, see when the 14th add is erm... added... The scrollbars don't update as though nothing has been added at all, yet the child count of the flowpanel specifically states that a child HAS been added...

If you get hold of this:
http://filedb.experts-exchange.com/incoming/2010/01_w06/229409/ProgressBarUpdate.zip

It'll demonstrate exactly what I mean. Also, as I previously mentioned the top is not aligned to the top of the parent panel, when there is little reason for it not to be.

Thanks,
Uni

Commented:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;

namespace ProgressBarUpdate{

    public partial class Form1 : Form{

        public Form1(){
            InitializeComponent();
        }

        private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e){
            vScrollBar1.Minimum = 0;
            if (flowLayoutPanel1.Size.Height > panel1.Size.Height)
            {
                vScrollBar1.Maximum = (flowLayoutPanel1.Size.Height - panel1.Size.Height) + vScrollBar1.LargeChange;
            }
            else
            {
                vScrollBar1.Maximum = 0;
            }
        }

        private void vScrollBar1_ValueChanged(object sender, EventArgs e){
            flowLayoutPanel1.Top = -vScrollBar1.Value;
        }

        private void button2_Click(object sender, EventArgs e){
                  Button b=new Button();
                  b.Text="Remove";
                  b.Click+=button1_Click;
            flowLayoutPanel1.Controls.Add(b);
        }

            private void button1_Click(object sender, EventArgs e) {
                  flowLayoutPanel1.Controls.Remove(sender as Control);
            }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }

}

Author

Commented:
It's still not right for the 14th add I'm afraid...

Commented:
Try it~

Author

Commented:
I have.

Commented:
So is the LargeChange fixed to 15? I don't understand why you insist use the LargeChange in the calculation.

Author

Commented:
>>So is the LargeChange fixed to 15?
No, I can't guarantee that...

>>I don't understand why you insist use the LargeChange in the calculation.
Because anything else is a hack... a magic number that works for this case and no others.

Commented:
Updated:
        private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e){
            vScrollBar1.Minimum = 0;
            if (flowLayoutPanel1.Size.Height > panel1.Size.Height)
            {
                vScrollBar1.Maximum = (flowLayoutPanel1.Size.Height - panel1.Size.Height) + 16;
            }
            else
            {
                vScrollBar1.Maximum = 0;
            }
        }

This code works for me. I don't see any point that you need to change the constant 16 into the vScrollBar1.LargeChange.

Commented:
The LargeChange is a variable at your design time. It is fixed to the end user. If you are asking a way to handle it correctly, I think it's possible:
You can define a private field, record the vScrollBar.LargeChange in Form_Load, then use it everytime you update the Layout.

Author

Commented:
Correct, it is fixed, which is why I don't understand why using it in place of a magic number stops it working correctly.
Commented:
If vScrollBar.Maxium - vScrollBar.Minium is less than the vScrollBar.LargeChange, vScrollBar.LargeChange is not always 15. You can set up a break point and verify it yourself.

Author

Commented:
I'm sure this is the completely wrong way of doing things... Nevertheless, I'll close this and see what I can find, if need be I'll get another question open.

Thanks,
Uni

Author

Commented:
Thanks.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial