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.
Original issue reported on code.google.com by heue...@gmail.com on 25 Mar 2009 at 8:15
Original issue reported on code.google.com by
heue...@gmail.com
on 25 Mar 2009 at 8:15