3 Star 4 Fork 1

徐振强/FastReport

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
ContainerObject.cs 13.16 KB
一键复制 编辑 原始数据 按行查看 历史
Fast Reports 提交于 2020-07-16 17:04 +08:00 . * sync 7/16/2020
using FastReport.Utils;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace FastReport
{
/// <summary>
/// Container object that may contain child objects.
/// </summary>
public partial class ContainerObject : ReportComponentBase, IParent
{
#region Fields
private ReportComponentCollection objects;
private bool updatingLayout;
private string beforeLayoutEvent;
private string afterLayoutEvent;
#endregion
#region Properties
/// <summary>
/// Gets the collection of child objects.
/// </summary>
[Browsable(false)]
public ReportComponentCollection Objects
{
get { return objects; }
}
/// <summary>
/// This event occurs before the container layouts its child objects.
/// </summary>
public event EventHandler BeforeLayout;
/// <summary>
/// This event occurs after the child objects layout was finished.
/// </summary>
public event EventHandler AfterLayout;
/// <summary>
/// Gets or sets a script event name that will be fired before the container layouts its child objects.
/// </summary>
[Category("Build")]
public string BeforeLayoutEvent
{
get { return beforeLayoutEvent; }
set { beforeLayoutEvent = value; }
}
/// <summary>
/// Gets or sets a script event name that will be fired after the child objects layout was finished.
/// </summary>
[Category("Build")]
public string AfterLayoutEvent
{
get { return afterLayoutEvent; }
set { afterLayoutEvent = value; }
}
#endregion
#region IParent
/// <inheritdoc/>
public virtual void GetChildObjects(ObjectCollection list)
{
foreach (ReportComponentBase c in objects)
{
list.Add(c);
}
}
/// <inheritdoc/>
public virtual bool CanContain(Base child)
{
return (child is ReportComponentBase);
}
/// <inheritdoc/>
public virtual void AddChild(Base child)
{
if (child is ReportComponentBase)
objects.Add(child as ReportComponentBase);
}
/// <inheritdoc/>
public virtual void RemoveChild(Base child)
{
if (child is ReportComponentBase)
objects.Remove(child as ReportComponentBase);
}
/// <inheritdoc/>
public virtual int GetChildOrder(Base child)
{
return objects.IndexOf(child as ReportComponentBase);
}
/// <inheritdoc/>
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);
}
}
/// <inheritdoc/>
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 Report engine
/// <inheritdoc/>
public override void SaveState()
{
base.SaveState();
SetRunning(true);
SetDesigning(false);
OnBeforePrint(EventArgs.Empty);
foreach (ReportComponentBase obj in Objects)
{
obj.SaveState();
obj.SetRunning(true);
obj.SetDesigning(false);
obj.OnBeforePrint(EventArgs.Empty);
}
}
/// <inheritdoc/>
public override void RestoreState()
{
OnAfterPrint(EventArgs.Empty);
base.RestoreState();
SetRunning(false);
foreach (ReportComponentBase obj in Objects)
{
obj.OnAfterPrint(EventArgs.Empty);
obj.RestoreState();
obj.SetRunning(false);
}
}
/// <inheritdoc/>
public override void GetData()
{
base.GetData();
foreach (ReportComponentBase obj in Objects)
{
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();
}
/// <inheritdoc/>
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;
}
OnAfterLayout(EventArgs.Empty);
return Height;
}
/// <summary>
/// This method fires the <b>BeforeLayout</b> event and the script code connected to the <b>BeforeLayoutEvent</b>.
/// </summary>
/// <param name="e">Event data.</param>
public void OnBeforeLayout(EventArgs e)
{
if (BeforeLayout != null)
BeforeLayout(this, e);
InvokeEvent(BeforeLayoutEvent, e);
}
/// <summary>
/// This method fires the <b>AfterLayout</b> event and the script code connected to the <b>AfterLayoutEvent</b>.
/// </summary>
/// <param name="e">Event data.</param>
public void OnAfterLayout(EventArgs e)
{
if (AfterLayout != null)
AfterLayout(this, e);
InvokeEvent(AfterLayoutEvent, e);
}
#endregion
#region Public methods
/// <inheritdoc/>
public override void Assign(Base source)
{
base.Assign(source);
ContainerObject src = source as ContainerObject;
BeforeLayoutEvent = src.BeforeLayoutEvent;
AfterLayoutEvent = src.AfterLayoutEvent;
}
/// <inheritdoc/>
public override void Serialize(FRWriter writer)
{
ContainerObject c = writer.DiffObject as ContainerObject;
base.Serialize(writer);
if (writer.SerializeTo == SerializeTo.Preview)
return;
if (BeforeLayoutEvent != c.BeforeLayoutEvent)
writer.WriteStr("BeforeLayoutEvent", BeforeLayoutEvent);
if (AfterLayoutEvent != c.AfterLayoutEvent)
writer.WriteStr("AfterLayoutEvent", AfterLayoutEvent);
}
/// <inheritdoc/>
public override void Draw(FRPaintEventArgs e)
{
DrawBackground(e);
DrawMarkers(e);
Border.Draw(e, new RectangleF(AbsLeft, AbsTop, Width, Height));
base.Draw(e);
}
#endregion
/// <summary>
/// Initializes a new instance of the <b>ContainerObject</b> class with default settings.
/// </summary>
public ContainerObject()
{
objects = new ReportComponentCollection(this);
beforeLayoutEvent = "";
afterLayoutEvent = "";
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xu_zhen_qiang/FastReport.git
git@gitee.com:xu_zhen_qiang/FastReport.git
xu_zhen_qiang
FastReport
FastReport
master

搜索帮助