Link to home
Start Free TrialLog in
Avatar of Unimatrix_001
Unimatrix_001Flag for United Kingdom of Great Britain and Northern Ireland

asked on

Issue setting .maximum on a scrollbar

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

Avatar of scottlafoy
scottlafoy
Flag of Canada image

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.
Avatar of Unimatrix_001

ASKER

I'm creating my own scrollbars, the flow panel is there just for testing...
vScrollBar1 = can you past the code here
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

Avatar of magicdlf
magicdlf

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

Give me a couple of mins and I'll upload the project...
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;
Hrm,

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

Thanks,
Uni
It's just pixels. Do not use LargeChange here and everything would be OK.
Here's the project...
SampleProject.zip
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. :(
Look at mine~ Surprisingly quite similar as yours. ;)
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
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
That is because:
The vScrollBar1.LargeChange becomes 1 after you setting:
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = 0;
Why is this?
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?
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
After all that - forgot to add it...
ProgressBarUpdate.zip
So is that working? What's the problem now?
No, I've got the original problem. When I use the LargeChange I don't get the correct increments.
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

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.
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???
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
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
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)
        {

        }

    }

}
It's still not right for the 14th add I'm afraid...
Try it~
I have.
So is the LargeChange fixed to 15? I don't understand why you insist use the LargeChange in the calculation.
>>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.
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.
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.
Correct, it is fixed, which is why I don't understand why using it in place of a magic number stops it working correctly.
ASKER CERTIFIED SOLUTION
Avatar of magicdlf
magicdlf

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Thanks.