Class PanelLayout
- Namespace
- Northwoods.Go.PanelLayouts
- Assembly
- Northwoods.GoDiagram.WinForms.dll
This is the abstract base class for all Panel Layouts, which inform the possible Panel types. It is possible to create your own Panel type by creating a subclass of PanelLayout, though this is not common and not recommended for beginners.
public abstract class PanelLayout
- Inheritance
-
PanelLayout
- Derived
- Inherited Members
Remarks
By default, GoDiagram has 12 Panel types, each corresponding to a PanelLayout subclass:
- "Position",
PanelLayoutPosition
- "Horizontal",
PanelLayoutHorizontal
- "Vertical",
PanelLayoutVertical
- "Spot",
PanelLayoutSpot
- "Auto",
PanelLayoutAuto
- "Table",
PanelLayoutTable
- "Viewbox",
PanelLayoutViewbox
- "TableRow",
PanelLayoutTableRow
- "TableColumn",
PanelLayoutTableColumn
- "Link",
PanelLayoutLink
- "Grid",
PanelLayoutGrid
- "Graduated",
PanelLayoutGraduated
Adding a new Layout is done by defining a new singleton class that extends PanelLayout.
Each PanelLayout must define a Measure(Panel, double, double, IList<GraphObject>, ref Rect, double, double) and Arrange(Panel, IList<GraphObject>, Rect) method. The measure method must call MeasureElement(GraphObject, double, double, double, double) with each element of the Panel, which sets each element's MeasuredBounds. These bounds can be used to determine object layout. The arrange method must call ArrangeElement(GraphObject, double, double, double, double, Rect?) with each element of the Panel to position the objects relative to the Panel. Remember that each Panel defines its own coordinate system, which is used for sizing and positioning of the panel's elements.
An instance of a PanelLayout is shared by all copies of a Panel that uses it.
There is an example PanelLayout in the PanelLayout sample.
Constructors
PanelLayout()
This class is abstract. Define your own subclass if you want to implement a custom panel layout.
public PanelLayout()
Methods
Arrange(Panel, IList<GraphObject>, Rect)
After measuring, a Panel must arrange each element, giving the elements a position and size in the Panel's coordinate system.
public virtual void Arrange(Panel panel, IList<GraphObject> elements, Rect union)
Parameters
panel
PanelPanel which called this layout
elements
IList<GraphObject>Array of Panel elements
union
Rect
Remarks
This must call ArrangeElement(GraphObject, double, double, double, double, Rect?) with each Panel element, which will set that element's ActualBounds.
For arranging some elements, it is useful to know the total unioned area of every element, which is given as the union
argument.
This Rect can be used to right-align or center-align, etc, elements within an area.
For example, PanelLayoutHorizontal arranges each element sequentially, starting with an X
value of 0
,
and increasing it by each previous element's MeasuredBounds Width
.
The horizontal Panel arranges each element with a Y
value determined by the union
argument's Height
considering the Alignment of the element, and the GraphObject's own MeasuredBounds Height
.
ArrangeElement(GraphObject, double, double, double, double, Rect?)
Arranges the GraphObject onto its parent Panel.
protected virtual void ArrangeElement(GraphObject obj, double x, double y, double width, double height, Rect? clipRect = null)
Parameters
obj
GraphObjectGraphObject to be arranged.
x
doubleThe final x value of ActualBounds that the Panel computes for the GraphObject.
y
doubleThe final y value of ActualBounds that the Panel computes for the GraphObject.
width
doubleThe final width value of ActualBounds that the Panel computes for the GraphObject.
height
doubleThe final height value of ActualBounds that the Panel computes for the GraphObject.
clipRect
Rect?an optional area to constrain this ActualBounds to when picking and drawing. By default, this is only used with Table Panel elements, which are clipped to their cell sizes.
Remarks
The passed-in numbers typically account for Margin and other offsets. This sets ActualBounds.
The x
and y
coordinates are where GraphObjects will be placed within the Panel's own coordinates
(from the Panel's top-left corner). The width
and height
are the size it will take up within the Panel's coordinates.
This sets the ActualBounds of the obj
.
Measure(Panel, double, double, IList<GraphObject>, ref Rect, double, double)
Given the available size, measure the Panel and determine its expected drawing size.
public virtual void Measure(Panel panel, double width, double height, IList<GraphObject> elements, ref Rect union, double minw, double minh)
Parameters
panel
PanelPanel which called this layout
width
doubleexpected width of the Panel, informed by any containing Panel and by the Panel's own DesiredSize, MinSize, and MaxSize. Often Infinity.
height
doubleexpected height of the Panel.
elements
IList<GraphObject>List of Panel elements
union
Rectrectangle to be modified to contain the expected union bounds of every element in the Panel, to be potentially used in Arrange(Panel, IList<GraphObject>, Rect).
minw
doubleexpected minimum width of the Panel, informed by any containing Panel. Often zero.
minh
doubleexpected minimum height of the Panel.
Remarks
This must call MeasureElement(GraphObject, double, double, double, double) with each Panel element, which will set the
MeasuredBounds of those elements. Depending on how the Panel intends to lay out its elements,
the programmer must construct the union
by setting union.Width
and union.Height
of the supplied argument.
For example PanelLayoutHorizontal measures its elements and sums their widths to set its union.Width
,
and takes the maximum of their heights to set its union.Height
.
This union must reflect the measured size of the Panel. After measure is called, the Panel class will modify this union Rect, constraining its size by the Panel's DesiredSize, MinSize, and MaxSize, before passing it to Arrange(Panel, IList<GraphObject>, Rect).
MeasureElement(GraphObject, double, double, double, double)
Given the available size, measure one element of the Panel and determine its expected drawing size. This sets the MeasuredBounds of the element, which can then be used to determine the arrangement of elements in the PanelLayout.
protected virtual void MeasureElement(GraphObject obj, double width, double height, double minw, double minh)
Parameters
obj
GraphObjectPanel which called this layout
width
doubleexpected width of the GraphObject
height
doubleexpected height of the GraphObject
minw
doubleminimum width of the GraphObject
minh
doubleminimum height of the GraphObject
RemeasureElement(GraphObject)
Uncommon: Force a given GraphObject to remeasure in the near future.
public void RemeasureElement(GraphObject obj)
Parameters
obj
GraphObject
Remarks
If a PanelLayout is not just measuring elements, but must also modify some of its elements, this must be called on those elements before modifications are made. This prevents the elements from potentially remeasuring the entire visual tree, which would cause an infinite loop.
Normally, panels do not modify the dimensions of their elements. In other words, a Panel would not normally set a property like DesiredSize or Text or Geometry on any of their elements. Some custom panels may wish to do this, especially if the programmer knows it will not affect the size of any containing Panel.
Calling this method before changing a property preempts the remeasuring of any containing Panels, ensuring only the GraphObject and its own child elements will be remeasured.
This is used in PanelLayoutViewbox on its one element. It modifies that element's Scale and is certain that will not affect Panels up the visual tree.