Status: New Owner: ---- Labels: Type-Defect OpSys-Windows Toolkit-Piccolo2D.NET
New issue 78 by heuermh: Problems using Piccolo 1.2.1.NET PScrollableContol with MS Visual Studio 2008 http://code.google.com/p/piccolo2d/issues/detail?id=78 From piccolo2d-dev: from pz0151 <steffen.ploetz at cityweb.de> to Piccolo2D Developers <piccolo2d-dev at googlegroups.com> date Wed, Mar 25, 2009 at 1:58 PM I wanted to use PScrollableContol with PCanvas and had some problems to get this combination run. Here are the rurn aronds i found: Step 1 ====== Placing a PScrollableContol onto a Panel causes an "object reference not set to an instance of an object" error in PScrollableContol.cs in line 624 public virtual Size GetViewSize(RectangleF bounds) { return scrollDirector.GetViewSize(bounds); } My suggestion: public virtual Size GetViewSize(RectangleF bounds) { if (scrollDirector != null) return scrollDirector.GetViewSize(bounds); else return new Size(); } Step 2 ====== After this repair placing a PScrollableContol onto a Panel causes an "object reference not set to an instance of an object" error in PScrollableContol.cs in line 515 protected override void OnLayout(LayoutEventArgs levent) { ... if (vsbNeeded) { vScrollBar.Height = availRect.Height; vScrollBar.Visible = true; } else { vScrollBar.Visible = false; } if (hsbNeeded) { hScrollBar.Width = availRect.Width; hScrollBar.Visible = true; } else { hScrollBar.Visible = false; } view.Size = availRect.Size; } My suggestion: protected override void OnLayout(LayoutEventArgs levent) { ... if (vsbNeeded && vScrollBar != null) { vScrollBar.Height = availRect.Height; vScrollBar.Visible = true; } else if (vScrollBar != null) { vScrollBar.Visible = false; } if (hsbNeeded && hScrollBar != null) { hScrollBar.Width = availRect.Width; hScrollBar.Visible = true; } else if (hScrollBar != null) { hScrollBar.Visible = false; } view.Size = availRect.Size; } Step 3 ====== After this repair placing a PScrollableContol onto a Panel causes an "object reference not set to an instance of an object" error in PScrollableContol.cs in line 526 protected override void OnLayout(LayoutEventArgs levent) { ... view.Size = availRect.Size; } My suggestion: protected override void OnLayout(LayoutEventArgs levent) { ... if (view != null) { view.Size = availRect.Size; } } Step 4 ====== Now we can error-free place a PScrollableContol onto a Panel and assign the Canvas property to a PCanvas. But starting the application causes a "object reference not set to an instance of an object" error in PScrollableContol.cs in line 594 public virtual Size Extent { get { int offset = 0; if (vScrollBar.Visible) { offset = DEFAULT_SCROLL_WIDTH; } int width = Math.Max(0, ClientRectangle.Width - offset); offset = 0; if (hScrollBar.Visible) { offset = DEFAULT_SCROLL_WIDTH; } int height = Math.Max(0, ClientRectangle.Height - offset); return new Size(width, height); } } Cause is the property initialization sequence, MS Visual Studio generates for our PScrollableContol: ... this.pScrollableControl1.AutoLargeChange = true; this.pScrollableControl1.AutoLargeChangeFactor = 0.9F; this.pScrollableControl1.Canvas = this.Panel_Content; ... AutoLargeChange is set before Canvas, but without canvas the vScrollBar and hScrollBar attributes of our PScrollableContol are not initialized. My suggestion: public virtual Size Extent { get { int offset = 0; if (vScrollBar != null && vScrollBar.Visible) { offset = DEFAULT_SCROLL_WIDTH; } int width = Math.Max(0, ClientRectangle.Width - offset); offset = 0; if (hScrollBar != null && hScrollBar.Visible) { offset = DEFAULT_SCROLL_WIDTH; } int height = Math.Max(0, ClientRectangle.Height - offset); return new Size(width, height); } } Step 5 ====== Another "object reference not set to an instance of an object" error in conjunction with this problem occurs in PScrollableContol.cs occurs in line 617, 644 and 543 public virtual Size ViewSize { get { return scrollDirector.GetViewSize(new RectangleF(0, 0, Extent.Width, Extent.Height)); } } public virtual Point ViewPosition { get { return scrollDirector.GetViewPosition(new RectangleF(0, 0, Extent.Width, Extent.Height)); } set { SetViewPosition(value, false); } } public virtual void UpdateScrollbars() { if (scrollable) { // update values Size s = ViewSize; Point p = ViewPosition; vScrollBar.Maximum = s.Height-(Extent.Height- VLargeChangePixels)-1; vScrollBar.Value = p.Y; hScrollBar.Maximum = s.Width-(Extent.Width-HLargeChangePixels)-1; hScrollBar.Value = p.X; // layout controls PerformLayout(); vScrollBar.SmallChange = VSmallChangePixels; vScrollBar.LargeChange = VLargeChangePixels; hScrollBar.SmallChange = HSmallChangePixels; hScrollBar.LargeChange = HLargeChangePixels; } } My suggestion: public virtual Size ViewSize { get { if (scrollDirector != null) { return scrollDirector.GetViewSize(new RectangleF (0, 0, Extent.Width, Extent.Height)); } else { return new Size(); } } } public virtual Point ViewPosition { get { if (scrollDirector != null) { return scrollDirector.GetViewPosition(new RectangleF(0, 0, Extent.Width, Extent.Height)); } else { return new Point(); } } set { SetViewPosition(value, false); } } public virtual void UpdateScrollbars() { if (scrollable) { // update values Size s = ViewSize; Point p = ViewPosition; if (vScrollBar != null) { vScrollBar.Maximum = s.Height-(Extent.Height- VLargeChangePixels)-1; vScrollBar.Value = p.Y; } if (hScrollBar != null) { hScrollBar.Maximum = s.Width-(Extent.Width- HLargeChangePixels)-1; hScrollBar.Value = p.X; } // layout controls PerformLayout(); if (vScrollBar != null) { vScrollBar.SmallChange = VSmallChangePixels; vScrollBar.LargeChange = VLargeChangePixels; } if (hScrollBar != null) { hScrollBar.SmallChange = HSmallChangePixels; hScrollBar.LargeChange = HLargeChangePixels; } } } Step 6 ====== Now the application can be started without runtime error, but the scroll bars are not placed at the right and bottom boundary of our PScrollableContol. My suggestion is to add a new method UpdateScrollbarLocations() for PScrollableContol after UpdateScrollbars(). /// <summary> /// Updates the locations of the scrollbars. /// </summary> public virtual void UpdateScrollbarLocations() { vScrollBar.Bounds = new Rectangle(ClientRectangle.Width - DEFAULT_SCROLL_WIDTH, ClientRectangle.Y, DEFAULT_SCROLL_WIDTH, ClientRectangle.Height - DEFAULT_SCROLL_WIDTH); hScrollBar.Bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Height - DEFAULT_SCROLL_WIDTH, ClientRectangle.Width - DEFAULT_SCROLL_WIDTH, DEFAULT_SCROLL_WIDTH); } And to call it in the application constructor after InitializeComponent (): InitializeComponent(); pScrollableControl1.UpdateScrollbarLocations(); Advice ====== To get use of the scroll capability, set PCanca's Layer size grater than PScrollableContol size. To adjust event argument positions to scroll positions use the Camera.ViewMatrix property. -- You received this message because you are listed in the owner or CC fields of this issue, or because you starred this issue. You may adjust your issue notification preferences at: http://code.google.com/hosting/settings --~--~---------~--~----~------------~-------~--~----~ Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en -~----------~----~----~----~------~----~------~--~---
