ScrollProperties.Value needs to be set twice?
-
Hey all, I've got some C# code that zooms in on an image contained in a Panel, and moves that panel's scroll bars to center on the place that was clicked on with the zoom tool. However, when I set the Value property of the ScrollProperties as shown below, the value stays the same unless I execute the same code twice in a row, as shown below. If I do it only once, it will center correctly, but the actual scroll bars will not move until the next set of the .Value property. Any ideas why?
/// /// Positions the vertial and horizontal scroll bars by the given X and Y offsets /// private void CenterScrollBars(int X, int Y) { //horizontal scroll bar first HScrollProperties hsp = MainPanel.HorizontalScroll; if (hsp.Visible) //if we don't have a scroll bar, don't try moving it! { //calculate the offset to move the scroll bar in order to center on the clicked point //since the point uses the DrawingBox's coordinate system, we need to move it into the //containing panel's coordinate system first by doing a shift int offs = (X + DrawBox.Location.X) - (MainPanel.Width / 2); MoveScrollPosition(hsp, offs); } //vertical next VScrollProperties vsp = MainPanel.VerticalScroll; if (vsp.Visible) //if we don't have a scroll bar, don't try moving it! { //same idea as above int offs = (Y + DrawBox.Location.Y) - (MainPanel.Height / 2); MoveScrollPosition(vsp, offs); } } /// /// Moves the scroll bar by the specified offset, clamping to min or maximum if needed /// /// The scroll bar to move /// The offset by which to move the scroll bar. private void MoveScrollPosition(ScrollProperties sp, int offset) { int val = sp.Value + offset; //clamp the value to the min and max values of the scroll bar if (val < sp.Minimum) { val = sp.Minimum; } else if (val > sp.Maximum) { val = sp.Maximum; } sp.Value = val; sp.Value = val; //TODO -- investigate this prob
-
Hey all, I've got some C# code that zooms in on an image contained in a Panel, and moves that panel's scroll bars to center on the place that was clicked on with the zoom tool. However, when I set the Value property of the ScrollProperties as shown below, the value stays the same unless I execute the same code twice in a row, as shown below. If I do it only once, it will center correctly, but the actual scroll bars will not move until the next set of the .Value property. Any ideas why?
/// /// Positions the vertial and horizontal scroll bars by the given X and Y offsets /// private void CenterScrollBars(int X, int Y) { //horizontal scroll bar first HScrollProperties hsp = MainPanel.HorizontalScroll; if (hsp.Visible) //if we don't have a scroll bar, don't try moving it! { //calculate the offset to move the scroll bar in order to center on the clicked point //since the point uses the DrawingBox's coordinate system, we need to move it into the //containing panel's coordinate system first by doing a shift int offs = (X + DrawBox.Location.X) - (MainPanel.Width / 2); MoveScrollPosition(hsp, offs); } //vertical next VScrollProperties vsp = MainPanel.VerticalScroll; if (vsp.Visible) //if we don't have a scroll bar, don't try moving it! { //same idea as above int offs = (Y + DrawBox.Location.Y) - (MainPanel.Height / 2); MoveScrollPosition(vsp, offs); } } /// /// Moves the scroll bar by the specified offset, clamping to min or maximum if needed /// /// The scroll bar to move /// The offset by which to move the scroll bar. private void MoveScrollPosition(ScrollProperties sp, int offset) { int val = sp.Value + offset; //clamp the value to the min and max values of the scroll bar if (val < sp.Minimum) { val = sp.Minimum; } else if (val > sp.Maximum) { val = sp.Maximum; } sp.Value = val; sp.Value = val; //TODO -- investigate this prob
Hi, I checked my code and I dont have this phenomenon; my scrollbars listen to every single Value change they get. But maybe it is caused by the way you have your Controls nested. :)
Luc Pattyn [My Articles] [Forum Guidelines]
-
Hey all, I've got some C# code that zooms in on an image contained in a Panel, and moves that panel's scroll bars to center on the place that was clicked on with the zoom tool. However, when I set the Value property of the ScrollProperties as shown below, the value stays the same unless I execute the same code twice in a row, as shown below. If I do it only once, it will center correctly, but the actual scroll bars will not move until the next set of the .Value property. Any ideas why?
/// /// Positions the vertial and horizontal scroll bars by the given X and Y offsets /// private void CenterScrollBars(int X, int Y) { //horizontal scroll bar first HScrollProperties hsp = MainPanel.HorizontalScroll; if (hsp.Visible) //if we don't have a scroll bar, don't try moving it! { //calculate the offset to move the scroll bar in order to center on the clicked point //since the point uses the DrawingBox's coordinate system, we need to move it into the //containing panel's coordinate system first by doing a shift int offs = (X + DrawBox.Location.X) - (MainPanel.Width / 2); MoveScrollPosition(hsp, offs); } //vertical next VScrollProperties vsp = MainPanel.VerticalScroll; if (vsp.Visible) //if we don't have a scroll bar, don't try moving it! { //same idea as above int offs = (Y + DrawBox.Location.Y) - (MainPanel.Height / 2); MoveScrollPosition(vsp, offs); } } /// /// Moves the scroll bar by the specified offset, clamping to min or maximum if needed /// /// The scroll bar to move /// The offset by which to move the scroll bar. private void MoveScrollPosition(ScrollProperties sp, int offset) { int val = sp.Value + offset; //clamp the value to the min and max values of the scroll bar if (val < sp.Minimum) { val = sp.Minimum; } else if (val > sp.Maximum) { val = sp.Maximum; } sp.Value = val; sp.Value = val; //TODO -- investigate this prob
Not sure why - but I just opened up System.Windows.Forms in reflector and looked at the Value property - the set_value has the following code;-
public void set_Value(int value) { if (this.value != value) { if ((value < this.minimum) || (value > this.maximum)) { throw new ArgumentOutOfRangeException("Value", SR.GetString("InvalidBoundArgument", new object[] { "Value", value.ToString(CultureInfo.CurrentCulture), "'minimum'", "'maximum'" })); } this.value = value; this.UpdateScrollInfo(); this.parent.SetDisplayFromScrollProps(this.HorizontalDisplayPosition, this.VerticalDisplayPosition); } }
If you follow the UpdateScrollInfo call - it ends up calling into the Windows API and calling SetScrollInfo on the control... If you follow SetDisplayFromScrollProps call it ends up calling a function called ApplyScrollbarChanges - which is one of the longest MS functions I have seen in a while - I'd look at the logic of that function and see if that is doing something weird.... Be interested to know if you crack the issue - my belief is that the first call fails (or appears to do nothing) - also maybe it's something simple like the control needs to be updated to reflect the change and ultimately calling the Value set property a second time causes that... Mark -
Hey all, I've got some C# code that zooms in on an image contained in a Panel, and moves that panel's scroll bars to center on the place that was clicked on with the zoom tool. However, when I set the Value property of the ScrollProperties as shown below, the value stays the same unless I execute the same code twice in a row, as shown below. If I do it only once, it will center correctly, but the actual scroll bars will not move until the next set of the .Value property. Any ideas why?
/// /// Positions the vertial and horizontal scroll bars by the given X and Y offsets /// private void CenterScrollBars(int X, int Y) { //horizontal scroll bar first HScrollProperties hsp = MainPanel.HorizontalScroll; if (hsp.Visible) //if we don't have a scroll bar, don't try moving it! { //calculate the offset to move the scroll bar in order to center on the clicked point //since the point uses the DrawingBox's coordinate system, we need to move it into the //containing panel's coordinate system first by doing a shift int offs = (X + DrawBox.Location.X) - (MainPanel.Width / 2); MoveScrollPosition(hsp, offs); } //vertical next VScrollProperties vsp = MainPanel.VerticalScroll; if (vsp.Visible) //if we don't have a scroll bar, don't try moving it! { //same idea as above int offs = (Y + DrawBox.Location.Y) - (MainPanel.Height / 2); MoveScrollPosition(vsp, offs); } } /// /// Moves the scroll bar by the specified offset, clamping to min or maximum if needed /// /// The scroll bar to move /// The offset by which to move the scroll bar. private void MoveScrollPosition(ScrollProperties sp, int offset) { int val = sp.Value + offset; //clamp the value to the min and max values of the scroll bar if (val < sp.Minimum) { val = sp.Minimum; } else if (val > sp.Maximum) { val = sp.Maximum; } sp.Value = val; sp.Value = val; //TODO -- investigate this prob
I've been able to reproduce the problem in a more simple environment. I have a Form that has one panel inside of it. Pressing "L" makes panel expand by 10 pixels each time, and programatically sets the scroll bar position if it is visible, and prints out the value. This code produces output: ---
0
5--- the first time you click L, and 5 every time after.
private void Form1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.L) { this.panel1.Width += 10; if (this.HScroll) { this.HorizontalScroll.Value = 5; Console.WriteLine(this.HorizontalScroll.Value); this.HorizontalScroll.Value = 5; Console.WriteLine(this.HorizontalScroll.Value); } } }
Still looking for a fix to avoid this hackeration, and would appreciate it if someone could run similar code on their box. Thanks, Phil
-
I've been able to reproduce the problem in a more simple environment. I have a Form that has one panel inside of it. Pressing "L" makes panel expand by 10 pixels each time, and programatically sets the scroll bar position if it is visible, and prints out the value. This code produces output: ---
0
5--- the first time you click L, and 5 every time after.
private void Form1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.L) { this.panel1.Width += 10; if (this.HScroll) { this.HorizontalScroll.Value = 5; Console.WriteLine(this.HorizontalScroll.Value); this.HorizontalScroll.Value = 5; Console.WriteLine(this.HorizontalScroll.Value); } } }
Still looking for a fix to avoid this hackeration, and would appreciate it if someone could run similar code on their box. Thanks, Phil