using System;
using System.Drawing;
using System.ComponentModel;
using System.Collections.Generic;
using FastReport.Utils;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Design;
namespace FastReport
{
///
/// Base class for all bands.
///
public abstract partial class BandBase : BreakableComponent, IParent
{
#region Fields
private ChildBand child;
private ReportComponentCollection objects;
private FloatCollection guides;
private bool startNewPage;
private bool firstRowStartsNewPage;
private bool printOnBottom;
private bool keepChild;
private string outlineExpression;
private int rowNo;
private int absRowNo;
private bool isFirstRow;
private bool isLastRow;
private bool repeated;
private bool updatingLayout;
private bool flagUseStartNewPage;
private bool flagCheckFreeSpace;
private bool flagMustBreak;
private int savedOriginalObjectsCount;
private float reprintOffset;
private string beforeLayoutEvent;
private string afterLayoutEvent;
private int repeatBandNTimes = 1;
#endregion
#region Properties
///
/// This event occurs before the band layouts its child objects.
///
public event EventHandler BeforeLayout;
///
/// This event occurs after the child objects layout was finished.
///
public event EventHandler AfterLayout;
///
/// Gets or sets a value indicating that the band should be printed from a new page.
///
///
/// New page is not generated when printing very first group or data row. This is made to avoid empty
/// first page.
///
[DefaultValue(false)]
[Category("Behavior")]
public bool StartNewPage
{
get { return startNewPage; }
set { startNewPage = value; }
}
///
/// Gets or sets a value that determines the number of repetitions of the same band.
///
[Category("Behavior")]
[DefaultValue(1)]
public int RepeatBandNTimes
{
get { return repeatBandNTimes; }
set { repeatBandNTimes = value; }
}
///
/// Gets or sets a value indicating that the first row can start a new report page.
///
///
/// Use this property if is set to true. Normally the new page
/// is not started when printing the first data row, to avoid empty first page.
///
[DefaultValue(true)]
[Category("Behavior")]
public bool FirstRowStartsNewPage
{
get { return firstRowStartsNewPage; }
set { firstRowStartsNewPage = value; }
}
///
/// Gets or sets a value indicating that the band should be printed on the page bottom.
///
[DefaultValue(false)]
[Category("Behavior")]
public bool PrintOnBottom
{
get { return printOnBottom; }
set { printOnBottom = value; }
}
///
/// Gets or sets a value indicating that the band should be printed together with its child band.
///
[DefaultValue(false)]
[Category("Behavior")]
public bool KeepChild
{
get { return keepChild; }
set { keepChild = value; }
}
///
/// Gets or sets an outline expression.
///
///
///
/// Outline is a tree control displayed in the preview window. It represents the prepared report structure.
/// Each outline node can be clicked to navigate to the item in the prepared report.
///
///
/// To create the outline, set this property to any valid expression that represents the outline node text.
/// This expression will be calculated when band is about to print, and its value will be added to the
/// outline. Thus, nodes' hierarchy in the outline is similar to the bands' hierarchy
/// in a report. That means there will be the main and subordinate outline nodes, corresponding
/// to the main and subordinate bands in a report (a report with two levels of data or with groups can
/// exemplify the point).
///
///
[Category("Navigation")]
[Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))]
public string OutlineExpression
{
get { return outlineExpression; }
set { outlineExpression = value; }
}
///
/// Gets or sets a child band that will be printed right after this band.
///
///
/// Typical use of child band is to print several objects that can grow or shrink. It also can be done
/// using the shift feature (via property), but in some cases it's not possible.
///
[Browsable(false)]
public ChildBand Child
{
get { return child; }
set
{
SetProp(child, value);
child = value;
}
}
///
/// Gets a collection of report objects belongs to this band.
///
[Browsable(false)]
public ReportComponentCollection Objects
{
get { return objects; }
}
///
/// Gets a value indicating that band is reprinted on a new page.
///
///
/// This property is applicable to the DataHeaderBand and GroupHeaderBand only.
/// It returns true if its RepeatOnAllPages property is true and band is
/// reprinted on a new page.
///
[Browsable(false)]
public bool Repeated
{
get { return repeated; }
set
{
repeated = value;
// set this flag for child bands as well
BandBase child = Child;
while (child != null)
{
child.Repeated = value;
child = child.Child;
}
}
}
///
/// Gets or sets a script event name that will be fired before the band layouts its child objects.
///
[Category("Build")]
public string BeforeLayoutEvent
{
get { return beforeLayoutEvent; }
set { beforeLayoutEvent = value; }
}
///
/// Gets or sets a script event name that will be fired after the child objects layout was finished.
///
[Category("Build")]
public string AfterLayoutEvent
{
get { return afterLayoutEvent; }
set { afterLayoutEvent = value; }
}
///
public override float AbsLeft
{
get { return IsRunning ? base.AbsLeft : Left; }
}
///
public override float AbsTop
{
get { return IsRunning ? base.AbsTop : Top; }
}
///
/// Gets or sets collection of guide lines for this band.
///
[Browsable(false)]
public FloatCollection Guides
{
get { return guides; }
set { guides = value; }
}
///
/// Gets a row number (the same value returned by the "Row#" system variable).
///
///
/// This property can be used when running a report. It may be useful to print hierarchical
/// row numbers in a master-detail report, like this:
/// 1.1
/// 1.2
/// 2.1
/// 2.2
/// To do this, put the Text object on a detail data band with the following text in it:
/// [Data1.RowNo].[Data2.RowNo]
///
[Browsable(false)]
public int RowNo
{
get { return rowNo; }
set
{
rowNo = value;
if (Child != null)
Child.RowNo = value;
}
}
///
/// Gets an absolute row number (the same value returned by the "AbsRow#" system variable).
///
[Browsable(false)]
public int AbsRowNo
{
get
{
return absRowNo;
}
set
{
absRowNo = value;
if (Child != null)
Child.AbsRowNo = value;
}
}
///
/// Gets a value indicating that this is the first data row.
///
[Browsable(false)]
public bool IsFirstRow
{
get { return isFirstRow; }
set { isFirstRow = value; }
}
///
/// Gets a value indicating that this is the last data row.
///
[Browsable(false)]
public bool IsLastRow
{
get { return isLastRow; }
set { isLastRow = value; }
}
internal bool HasBorder
{
get { return !Border.Equals(new Border()); }
}
internal bool HasFill
{
get { return !Fill.IsTransparent; }
}
internal DataBand ParentDataBand
{
get
{
Base c = Parent;
while (c != null)
{
if (c is DataBand)
return c as DataBand;
if (c is ReportPage && (c as ReportPage).Subreport != null)
c = (c as ReportPage).Subreport;
c = c.Parent;
}
return null;
}
}
internal bool FlagUseStartNewPage
{
get { return flagUseStartNewPage; }
set { flagUseStartNewPage = value; }
}
internal bool FlagCheckFreeSpace
{
get { return flagCheckFreeSpace; }
set
{
flagCheckFreeSpace = value;
// set flag for child bands as well
BandBase child = Child;
while (child != null)
{
child.FlagCheckFreeSpace = value;
child = child.Child;
}
}
}
internal bool FlagMustBreak
{
get { return flagMustBreak; }
set { flagMustBreak = value; }
}
internal float ReprintOffset
{
get { return reprintOffset; }
set { reprintOffset = value; }
}
internal float PageWidth
{
get
{
ReportPage page = Page as ReportPage;
if (page != null)
return page.WidthInPixels - (page.LeftMargin + page.RightMargin) * Units.Millimeters;
return 0;
}
}
#endregion
#region IParent Members
///
public virtual void GetChildObjects(ObjectCollection list)
{
foreach (ReportComponentBase obj in objects)
{
list.Add(obj);
}
if (!IsRunning)
list.Add(child);
}
///
public virtual bool CanContain(Base child)
{
if (IsRunning)
return child is ReportComponentBase;
return ((child is ReportComponentBase && !(child is BandBase)) || child is ChildBand);
}
///
public virtual void AddChild(Base child)
{
if (child is ChildBand && !IsRunning)
Child = child as ChildBand;
else
objects.Add(child as ReportComponentBase);
}
///
public virtual void RemoveChild(Base child)
{
if (child is ChildBand && this.child == child as ChildBand)
Child = null;
else
objects.Remove(child as ReportComponentBase);
}
///
public virtual int GetChildOrder(Base child)
{
return objects.IndexOf(child as ReportComponentBase);
}
///
public virtual void SetChildOrder(Base child, int order)
{
int oldOrder = child.ZOrder;
if (oldOrder != -1 && order != -1 && oldOrder != order)
{
if (order > objects.Count)
order = objects.Count;
if (oldOrder <= order)
order--;
objects.Remove(child as ReportComponentBase);
objects.Insert(order, child as ReportComponentBase);
UpdateLayout(0, 0);
}
}
///
public virtual void UpdateLayout(float dx, float dy)
{
if (updatingLayout)
return;
updatingLayout = true;
try
{
RectangleF remainingBounds = new RectangleF(0, 0, Width, Height);
remainingBounds.Width += dx;
remainingBounds.Height += dy;
foreach (ReportComponentBase c in Objects)
{
if ((c.Anchor & AnchorStyles.Right) != 0)
{
if ((c.Anchor & AnchorStyles.Left) != 0)
c.Width += dx;
else
c.Left += dx;
}
else if ((c.Anchor & AnchorStyles.Left) == 0)
{
c.Left += dx / 2;
}
if ((c.Anchor & AnchorStyles.Bottom) != 0)
{
if ((c.Anchor & AnchorStyles.Top) != 0)
c.Height += dy;
else
c.Top += dy;
}
else if ((c.Anchor & AnchorStyles.Top) == 0)
{
c.Top += dy / 2;
}
switch (c.Dock)
{
case DockStyle.Left:
c.Bounds = new RectangleF(remainingBounds.Left, remainingBounds.Top, c.Width, remainingBounds.Height);
remainingBounds.X += c.Width;
remainingBounds.Width -= c.Width;
break;
case DockStyle.Top:
c.Bounds = new RectangleF(remainingBounds.Left, remainingBounds.Top, remainingBounds.Width, c.Height);
remainingBounds.Y += c.Height;
remainingBounds.Height -= c.Height;
break;
case DockStyle.Right:
c.Bounds = new RectangleF(remainingBounds.Right - c.Width, remainingBounds.Top, c.Width, remainingBounds.Height);
remainingBounds.Width -= c.Width;
break;
case DockStyle.Bottom:
c.Bounds = new RectangleF(remainingBounds.Left, remainingBounds.Bottom - c.Height, remainingBounds.Width, c.Height);
remainingBounds.Height -= c.Height;
break;
case DockStyle.Fill:
c.Bounds = remainingBounds;
remainingBounds.Width = 0;
remainingBounds.Height = 0;
break;
}
}
}
finally
{
updatingLayout = false;
}
}
#endregion
#region Public Methods
///
public override void Assign(Base source)
{
base.Assign(source);
BandBase src = source as BandBase;
Guides.Assign(src.Guides);
StartNewPage = src.StartNewPage;
FirstRowStartsNewPage = src.FirstRowStartsNewPage;
PrintOnBottom = src.PrintOnBottom;
KeepChild = src.KeepChild;
OutlineExpression = src.OutlineExpression;
BeforeLayoutEvent = src.BeforeLayoutEvent;
AfterLayoutEvent = src.AfterLayoutEvent;
RepeatBandNTimes = src.RepeatBandNTimes;
IsLastRow = src.IsLastRow;
}
internal virtual void UpdateWidth()
{
// update band width. It is needed for anchor/dock
ReportPage page = Page as ReportPage;
if (page != null && !(page.UnlimitedWidth && IsDesigning))
{
if (page.Columns.Count <= 1 || !IsColumnDependentBand)
Width = PageWidth;
}
}
///
public override List Validate()
{
return new List();
}
///
public override void Serialize(FRWriter writer)
{
BandBase c = writer.DiffObject as BandBase;
base.Serialize(writer);
if (writer.SerializeTo == SerializeTo.Preview)
return;
if (StartNewPage != c.StartNewPage)
writer.WriteBool("StartNewPage", StartNewPage);
if (FirstRowStartsNewPage != c.FirstRowStartsNewPage)
writer.WriteBool("FirstRowStartsNewPage", FirstRowStartsNewPage);
if (PrintOnBottom != c.PrintOnBottom)
writer.WriteBool("PrintOnBottom", PrintOnBottom);
if (KeepChild != c.KeepChild)
writer.WriteBool("KeepChild", KeepChild);
if (OutlineExpression != c.OutlineExpression)
writer.WriteStr("OutlineExpression", OutlineExpression);
if (Guides.Count > 0)
writer.WriteValue("Guides", Guides);
if (BeforeLayoutEvent != c.BeforeLayoutEvent)
writer.WriteStr("BeforeLayoutEvent", BeforeLayoutEvent);
if (AfterLayoutEvent != c.AfterLayoutEvent)
writer.WriteStr("AfterLayoutEvent", AfterLayoutEvent);
if (RepeatBandNTimes != c.RepeatBandNTimes)
writer.WriteInt("RepeatBandNTimes", RepeatBandNTimes);
}
internal bool IsColumnDependentBand
{
get
{
BandBase b = this;
if (b is ChildBand)
{
while (b is ChildBand)
{
b = b.Parent as BandBase;
}
}
if (b is DataHeaderBand || b is DataBand || b is DataFooterBand ||
b is GroupHeaderBand || b is GroupFooterBand ||
b is ColumnHeaderBand || b is ColumnFooterBand || b is ReportSummaryBand)
return true;
return false;
}
}
#endregion
#region Report Engine
internal void SetUpdatingLayout(bool value)
{
updatingLayout = value;
}
///
public override string[] GetExpressions()
{
List expressions = new List();
expressions.AddRange(base.GetExpressions());
if (!String.IsNullOrEmpty(OutlineExpression))
expressions.Add(OutlineExpression);
return expressions.ToArray();
}
///
public override void SaveState()
{
base.SaveState();
savedOriginalObjectsCount = Objects.Count;
SetRunning(true);
SetDesigning(false);
OnBeforePrint(EventArgs.Empty);
foreach (ReportComponentBase obj in Objects)
{
obj.SaveState();
obj.SetRunning(true);
obj.SetDesigning(false);
obj.OnBeforePrint(EventArgs.Empty);
}
//Report.Engine.TranslatedObjectsToBand(this);
// apply even style
if (RowNo % 2 == 0)
{
ApplyEvenStyle();
foreach (ReportComponentBase obj in Objects)
{
obj.ApplyEvenStyle();
}
}
}
///
public override void RestoreState()
{
OnAfterPrint(EventArgs.Empty);
base.RestoreState();
while (Objects.Count > savedOriginalObjectsCount)
{
Objects[Objects.Count - 1].Dispose();
}
SetRunning(false);
ReportComponentCollection collection_clone = new ReportComponentCollection();
Objects.CopyTo(collection_clone);
foreach (ReportComponentBase obj in collection_clone)
{
obj.OnAfterPrint(EventArgs.Empty);
obj.RestoreState();
obj.SetRunning(false);
}
}
///
public override float CalcHeight()
{
OnBeforeLayout(EventArgs.Empty);
// sort objects by Top
ReportComponentCollection sortedObjects = Objects.SortByTop();
// calc height of each object
float[] heights = new float[sortedObjects.Count];
for (int i = 0; i < sortedObjects.Count; i++)
{
ReportComponentBase obj = sortedObjects[i];
float height = obj.Height;
if (obj.Visible && (obj.CanGrow || obj.CanShrink))
{
float height1 = obj.CalcHeight();
if ((obj.CanGrow && height1 > height) || (obj.CanShrink && height1 < height))
height = height1;
}
heights[i] = height;
}
// calc shift amounts
float[] shifts = new float[sortedObjects.Count];
for (int i = 0; i < sortedObjects.Count; i++)
{
ReportComponentBase parent = sortedObjects[i];
float shift = heights[i] - parent.Height;
if (shift == 0)
continue;
for (int j = i + 1; j < sortedObjects.Count; j++)
{
ReportComponentBase child = sortedObjects[j];
if (child.ShiftMode == ShiftMode.Never)
continue;
if (child.Top >= parent.Bottom - 1e-4)
{
if (child.ShiftMode == ShiftMode.WhenOverlapped &&
(child.Left > parent.Right - 1e-4 || parent.Left > child.Right - 1e-4))
continue;
float parentShift = shifts[i];
float childShift = shifts[j];
if (shift > 0)
childShift = Math.Max(shift + parentShift, childShift);
else
childShift = Math.Min(shift + parentShift, childShift);
shifts[j] = childShift;
}
}
}
// update location and size of each component, calc max height
float maxHeight = 0;
for (int i = 0; i < sortedObjects.Count; i++)
{
ReportComponentBase obj = sortedObjects[i];
DockStyle saveDock = obj.Dock;
obj.Dock = DockStyle.None;
obj.Height = heights[i];
obj.Top += shifts[i];
if (obj.Visible && obj.Bottom > maxHeight)
maxHeight = obj.Bottom;
obj.Dock = saveDock;
}
if ((CanGrow && maxHeight > Height) || (CanShrink && maxHeight < Height))
Height = maxHeight;
// perform grow to bottom
foreach (ReportComponentBase obj in Objects)
{
if (obj.GrowToBottom)
{
obj.Height = Height - obj.Top;
// reserve place for border
if (IsLastRow && obj.Border.Lines.HasFlag(BorderLines.Bottom))
obj.Height -= Border.BottomLine.Width;
}
}
OnAfterLayout(EventArgs.Empty);
return Height;
}
///
public void AddLastToFooter(BreakableComponent breakTo)
{
float maxTop = (AllObjects[0] as ComponentBase).Top;
for (int i = 0; i < AllObjects.Count; i++)
{
if (AllObjects[i] is ComponentBase)
{
ComponentBase obj = AllObjects[i] as ComponentBase;
if (obj.Top > maxTop && !(obj is DataFooterBand))
maxTop = obj.Top;
}
}
float breakLine = maxTop;
List pasteList = new List();
foreach (ReportComponentBase obj in Objects)
if (obj.Bottom > breakLine)
pasteList.Add(obj);
int itemsBefore = breakTo.AllObjects.Count;
foreach (ReportComponentBase obj in pasteList)
{
if (obj.Top < breakLine)
{
BreakableComponent breakComp = Activator.CreateInstance(obj.GetType()) as BreakableComponent;
breakComp.AssignAll(obj);
breakComp.Parent = breakTo;
breakComp.CanGrow = true;
breakComp.CanShrink = false;
breakComp.Height -= breakLine - obj.Top;
breakComp.Top = 0;
obj.Height = breakLine - obj.Top;
(obj as BreakableComponent).Break(breakComp);
}
else
{
obj.Top -= breakLine;
obj.Parent = breakTo;
continue;
}
}
float minTop = (breakTo.AllObjects[0] as ComponentBase).Top;
float maxBottom = 0;
for (int i = itemsBefore; i < breakTo.AllObjects.Count; i++)
if (breakTo.AllObjects[i] is ComponentBase)
if ((breakTo.AllObjects[i] as ComponentBase).Top < minTop && breakTo.AllObjects[i] is ReportComponentBase && !(breakTo.AllObjects[i] is Table.TableCell))
minTop = (breakTo.AllObjects[i] as ComponentBase).Top;
for (int i = itemsBefore; i < breakTo.AllObjects.Count; i++)
if (breakTo.AllObjects[i] is ComponentBase)
if ((breakTo.AllObjects[i] as ComponentBase).Bottom > maxBottom && breakTo.AllObjects[i] is ReportComponentBase && !(breakTo.AllObjects[i] is Table.TableCell))
maxBottom = (breakTo.AllObjects[i] as ComponentBase).Bottom;
for (int i = 0; i < itemsBefore; i++)
if (breakTo.AllObjects[i] is ComponentBase)
(breakTo.AllObjects[i] as ComponentBase).Top += maxBottom - minTop;
breakTo.Height += maxBottom - minTop;
Height -= maxBottom - minTop;
}
///
public override bool Break(BreakableComponent breakTo)
{
// first we find the break line. It's a minimum Top coordinate of the object that cannot break.
float breakLine = Height;
float excessiveHeight = 0;
float maxExcessiveHeight = 0;
Dictionary excessiveHeights = new Dictionary();
bool breakLineFound = true;
do
{
breakLineFound = true;
foreach (ReportComponentBase obj in Objects)
{
bool canBreak = true;
if (obj.Top < breakLine && obj.Bottom > breakLine)
{
canBreak = false;
BreakableComponent breakable = obj as BreakableComponent;
if (breakable != null && breakable.CanBreak)
{
using (BreakableComponent clone = Activator.CreateInstance(breakable.GetType()) as BreakableComponent)
{
clone.AssignAll(breakable);
clone.Height = breakLine - clone.Top;
// to allow access to the Report
clone.Parent = breakTo;
canBreak = clone.Break(null, out excessiveHeight);
if (excessiveHeight > 0)
{
excessiveHeights.Add(clone.Bounds, excessiveHeight);
maxExcessiveHeight = Math.Max(maxExcessiveHeight, excessiveHeight);
}
}
}
}
if (!canBreak)
{
breakLine = Math.Min(obj.Top, breakLine);
// enumerate objects again
breakLineFound = false;
break;
}
}
}
while (!breakLineFound);
// now break the components
int i = 0;
while (i < Objects.Count)
{
ReportComponentBase obj = Objects[i];
if (obj.Bottom > breakLine)
{
if (obj.Top < breakLine)
{
BreakableComponent breakComp = Activator.CreateInstance(obj.GetType()) as BreakableComponent;
breakComp.AssignAll(obj);
breakComp.Parent = breakTo;
breakComp.CanGrow = true;
breakComp.CanShrink = false;
breakComp.Height -= breakLine - obj.Top;
breakComp.Top = 0;
obj.Height = breakLine - obj.Top;
(obj as BreakableComponent).Break(breakComp);
}
else
{
float currentExcessiveHeight = 0;
foreach(var item in excessiveHeights)
{
if ((Math.Round(obj.Left, 2) <= Math.Round(item.Key.Left, 2) && Math.Round(obj.Right, 2) >= Math.Round(item.Key.Left, 2)) ||
(Math.Round(obj.Left, 2) >= Math.Round(item.Key.Left, 2) && Math.Round(item.Key.Right, 2) >= Math.Round(obj.Left, 2)))
currentExcessiveHeight = Math.Max(currentExcessiveHeight, item.Value);
}
// (case: object with Anchor = bottom on a breakable band)
// in case of bottom anchor, do not move the object. It will be moved automatically when we decrease the band height
if ((obj.Anchor & AnchorStyles.Bottom) == 0)
obj.Top -= (breakLine - currentExcessiveHeight);
obj.Parent = breakTo;
continue;
}
}
i++;
}
Height = breakLine;
breakTo.Height -= (breakLine - maxExcessiveHeight);
return Objects.Count > 0;
}
///
public override void GetData()
{
base.GetData();
FRCollectionBase list = new FRCollectionBase();
Objects.CopyTo(list);
foreach (ReportComponentBase obj in list)
{
obj.GetData();
obj.OnAfterData();
// break the component if it is of BreakableComponent an has non-empty BreakTo property
if (obj is BreakableComponent && (obj as BreakableComponent).BreakTo != null &&
(obj as BreakableComponent).BreakTo.GetType() == obj.GetType())
(obj as BreakableComponent).Break((obj as BreakableComponent).BreakTo);
}
OnAfterData();
}
internal virtual bool IsEmpty()
{
return true;
}
private void AddBookmark(ReportComponentBase obj)
{
if (Report != null)
Report.Engine.AddBookmark(obj.Bookmark);
}
internal void AddBookmarks()
{
AddBookmark(this);
foreach (ReportComponentBase obj in Objects)
{
AddBookmark(obj);
}
}
///
public override void InitializeComponent()
{
base.InitializeComponent();
AbsRowNo = 0;
}
///
/// This method fires the BeforeLayout event and the script code connected to the BeforeLayoutEvent.
///
/// Event data.
public void OnBeforeLayout(EventArgs e)
{
if (BeforeLayout != null)
BeforeLayout(this, e);
InvokeEvent(BeforeLayoutEvent, e);
}
///
/// This method fires the AfterLayout event and the script code connected to the AfterLayoutEvent.
///
/// Event data.
public void OnAfterLayout(EventArgs e)
{
if (AfterLayout != null)
AfterLayout(this, e);
InvokeEvent(AfterLayoutEvent, e);
}
#endregion
///
/// Initializes a new instance of the class with default settings.
///
public BandBase()
{
objects = new ReportComponentCollection(this);
guides = new FloatCollection();
beforeLayoutEvent = "";
afterLayoutEvent = "";
outlineExpression = "";
CanBreak = false;
ShiftMode = ShiftMode.Never;
if (BaseName.EndsWith("Band"))
BaseName = ClassName.Remove(ClassName.IndexOf("Band"));
SetFlags(Flags.CanMove | Flags.CanChangeOrder | Flags.CanChangeParent | Flags.CanCopy | Flags.CanGroup, false);
FlagUseStartNewPage = true;
FlagCheckFreeSpace = true;
}
}
}