123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- using System.ComponentModel;
- using FastReport.Utils;
- using FastReport.Data;
- using System.Drawing.Design;
- namespace FastReport
- {
- /// <summary>
- /// Specifies a sort order.
- /// </summary>
- /// <remarks>
- /// This enumeration is used in the group header and in the "Matrix" object.
- /// </remarks>
- public enum SortOrder
- {
- /// <summary>
- /// Specifies no sort (natural order).
- /// </summary>
- None,
- /// <summary>
- /// Specifies an ascending sort order.
- /// </summary>
- Ascending,
- /// <summary>
- /// Specifies a descending sort order.
- /// </summary>
- Descending
- }
- /// <summary>
- /// Represents a group header band.
- /// </summary>
- /// <remarks>
- /// A simple group consists of one <b>GroupHeaderBand</b> and the <b>DataBand</b> that is set
- /// to the <see cref="Data"/> property. To create the nested groups, use the <see cref="NestedGroup"/> property.
- /// <note type="caution">
- /// Only the last nested group can have data band.
- /// </note>
- /// <para/>Use the <see cref="Condition"/> property to set the group condition. The <see cref="SortOrder"/>
- /// property can be used to set the sort order for group's data rows. You can also use the <b>Sort</b>
- /// property of the group's <b>DataBand</b> to specify additional sort.
- /// </remarks>
- /// <example>This example shows how to create nested groups.
- /// <code>
- /// ReportPage page = report.Pages[0] as ReportPage;
- ///
- /// // create the main group
- /// GroupHeaderBand mainGroup = new GroupHeaderBand();
- /// mainGroup.Height = Units.Millimeters * 10;
- /// mainGroup.Name = "MainGroup";
- /// mainGroup.Condition = "[Orders.CustomerName]";
- /// // add a group to the page
- /// page.Bands.Add(mainGroup);
- ///
- /// // create the nested group
- /// GroupHeaderBand nestedGroup = new GroupHeaderBand();
- /// nestedGroup.Height = Units.Millimeters * 10;
- /// nestedGroup.Name = "NestedGroup";
- /// nestedGroup.Condition = "[Orders.OrderDate]";
- /// // add it to the main group
- /// mainGroup.NestedGroup = nestedGroup;
- ///
- /// // create a data band
- /// DataBand dataBand = new DataBand();
- /// dataBand.Height = Units.Millimeters * 10;
- /// dataBand.Name = "GroupData";
- /// dataBand.DataSource = report.GetDataSource("Orders");
- /// // connect the databand to the nested group
- /// nestedGroup.Data = dataBand;
- /// </code>
- /// </example>
- public partial class GroupHeaderBand : HeaderFooterBandBase
- {
- #region Fields
- private GroupHeaderBand nestedGroup;
- private DataBand data;
- private GroupFooterBand groupFooter;
- private DataHeaderBand header;
- private DataFooterBand footer;
- private string condition;
- private SortOrder sortOrder;
- private bool keepTogether;
- private bool resetPageNumber;
- private object groupValue;
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets a nested group.
- /// </summary>
- /// <remarks>
- /// Use this property to create nested groups.
- /// <note type="caution">
- /// Only the last nested group can have data band.
- /// </note>
- /// </remarks>
- /// <example>
- /// This example demonstrates how to create a group with nested group.
- /// <code>
- /// ReportPage page;
- /// GroupHeaderBand group = new GroupHeaderBand();
- /// group.NestedGroup = new GroupHeaderBand();
- /// group.NestedGroup.Data = new DataBand();
- /// page.Bands.Add(group);
- /// </code>
- /// </example>
- [Browsable(false)]
- public GroupHeaderBand NestedGroup
- {
- get { return nestedGroup; }
- set
- {
- SetProp(nestedGroup, value);
- nestedGroup = value;
- }
- }
- /// <summary>
- /// Gets or sets the group data band.
- /// </summary>
- /// <remarks>
- /// Use this property to add a data band to a group. Note: only the last nested group can have Data band.
- /// </remarks>
- /// <example>
- /// This example demonstrates how to add a data band to a group.
- /// <code>
- /// ReportPage page;
- /// GroupHeaderBand group = new GroupHeaderBand();
- /// group.Data = new DataBand();
- /// page.Bands.Add(group);
- /// </code>
- /// </example>
- [Browsable(false)]
- public DataBand Data
- {
- get { return data; }
- set
- {
- SetProp(data, value);
- data = value;
- }
- }
- /// <summary>
- /// Gets or sets a group footer.
- /// </summary>
- [Browsable(false)]
- public GroupFooterBand GroupFooter
- {
- get { return groupFooter; }
- set
- {
- SetProp(groupFooter, value);
- groupFooter = value;
- }
- }
- /// <summary>
- /// Gets or sets a header band.
- /// </summary>
- [Browsable(false)]
- public DataHeaderBand Header
- {
- get { return header; }
- set
- {
- SetProp(header, value);
- header = value;
- }
- }
- /// <summary>
- /// Gets or sets a footer band.
- /// </summary>
- /// <remarks>
- /// To access a group footer band, use the <see cref="GroupFooter"/> property.
- /// </remarks>
- [Browsable(false)]
- public DataFooterBand Footer
- {
- get { return footer; }
- set
- {
- SetProp(footer, value);
- footer = value;
- }
- }
- /// <summary>
- /// Gets or sets the group condition.
- /// </summary>
- /// <remarks>
- /// This property can contain any valid expression. When running a report, this expression is calculated
- /// for each data row. When the value of this condition is changed, FastReport starts a new group.
- /// </remarks>
- [Category("Data")]
- [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))]
- public string Condition
- {
- get { return condition; }
- set { condition = value; }
- }
- /// <summary>
- /// Gets or sets the sort order.
- /// </summary>
- /// <remarks>
- /// FastReport can sort data rows automatically using the <see cref="Condition"/> value.
- /// </remarks>
- [DefaultValue(SortOrder.Ascending)]
- [Category("Behavior")]
- public SortOrder SortOrder
- {
- get { return sortOrder; }
- set { sortOrder = value; }
- }
- /// <summary>
- /// Gets or sets a value indicating that the group should be printed together on one page.
- /// </summary>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool KeepTogether
- {
- get { return keepTogether; }
- set { keepTogether = value; }
- }
- /// <summary>
- /// Gets or sets a value that determines whether to reset the page numbers when this group starts print.
- /// </summary>
- /// <remarks>
- /// Typically you should set the <see cref="BandBase.StartNewPage"/> property to <b>true</b> as well.
- /// </remarks>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool ResetPageNumber
- {
- get { return resetPageNumber; }
- set { resetPageNumber = value; }
- }
- internal DataSourceBase DataSource
- {
- get
- {
- DataBand dataBand = GroupDataBand;
- return dataBand == null ? null : dataBand.DataSource;
- }
- }
- internal DataBand GroupDataBand
- {
- get
- {
- GroupHeaderBand group = this;
- while (group != null)
- {
- if (group.Data != null)
- return group.Data;
- group = group.NestedGroup;
- }
- return null;
- }
- }
- #endregion
- #region IParent
- /// <inheritdoc/>
- public override void GetChildObjects(ObjectCollection list)
- {
- base.GetChildObjects(list);
- if (!IsRunning)
- {
- list.Add(header);
- list.Add(nestedGroup);
- list.Add(data);
- list.Add(groupFooter);
- list.Add(footer);
- }
- }
- /// <inheritdoc/>
- public override bool CanContain(Base child)
- {
- return base.CanContain(child) ||
- (child is DataBand && nestedGroup == null && data == null) ||
- (child is GroupHeaderBand && (nestedGroup == null || nestedGroup is GroupHeaderBand) && data == null) ||
- child is GroupFooterBand || child is DataHeaderBand || child is DataFooterBand;
- }
- /// <inheritdoc/>
- public override void AddChild(Base child)
- {
- if (IsRunning)
- {
- base.AddChild(child);
- return;
- }
- if (child is GroupHeaderBand)
- NestedGroup = child as GroupHeaderBand;
- else if (child is DataBand)
- Data = child as DataBand;
- else if (child is GroupFooterBand)
- GroupFooter = child as GroupFooterBand;
- else if (child is DataHeaderBand)
- Header = child as DataHeaderBand;
- else if (child is DataFooterBand)
- Footer = child as DataFooterBand;
- else
- base.AddChild(child);
- }
- /// <inheritdoc/>
- public override void RemoveChild(Base child)
- {
- base.RemoveChild(child);
- if (IsRunning)
- return;
- if (child is GroupHeaderBand && nestedGroup == child)
- NestedGroup = null;
- if (child is DataBand && data == child as DataBand)
- Data = null;
- if (child is GroupFooterBand && groupFooter == child)
- GroupFooter = null;
- if (child is DataHeaderBand && header == child)
- Header = null;
- if (child is DataFooterBand && footer == child)
- Footer = null;
- }
- #endregion
- #region Public Methods
- /// <inheritdoc/>
- public override void Assign(Base source)
- {
- base.Assign(source);
- GroupHeaderBand src = source as GroupHeaderBand;
- Condition = src.Condition;
- SortOrder = src.SortOrder;
- KeepTogether = src.KeepTogether;
- ResetPageNumber = src.ResetPageNumber;
- }
- /// <inheritdoc/>
- public override void Serialize(FRWriter writer)
- {
- GroupHeaderBand c = writer.DiffObject as GroupHeaderBand;
- base.Serialize(writer);
- if (writer.SerializeTo == SerializeTo.Preview)
- return;
- if (Condition != c.Condition)
- writer.WriteStr("Condition", Condition);
- if (SortOrder != c.SortOrder)
- writer.WriteValue("SortOrder", SortOrder);
- if (KeepTogether != c.KeepTogether)
- writer.WriteBool("KeepTogether", KeepTogether);
- if (ResetPageNumber != c.ResetPageNumber)
- writer.WriteBool("ResetPageNumber", ResetPageNumber);
- }
- /// <inheritdoc/>
- public override string[] GetExpressions()
- {
- return new string[] { Condition };
- }
- internal override bool IsEmpty()
- {
- if (NestedGroup != null)
- return NestedGroup.IsEmpty();
- else if (Data != null)
- return Data.IsEmpty();
- return base.IsEmpty();
- }
- internal void InitDataSource()
- {
- DataBand dataBand = GroupDataBand;
- GroupHeaderBand group = this;
- int index = 0;
- // insert group sort to the databand
- while (group != null)
- {
- if (group.SortOrder != SortOrder.None)
- {
- dataBand.Sort.Insert(index, new Sort(group.Condition, group.SortOrder == SortOrder.Descending));
- index++;
- }
- group = group.NestedGroup;
- }
- dataBand.InitDataSource();
- }
- internal void FinalizeDataSource()
- {
- DataBand dataBand = GroupDataBand;
- GroupHeaderBand group = this;
- // remove group sort from the databand
- while (group != null)
- {
- if (group.SortOrder != SortOrder.None)
- dataBand.Sort.RemoveAt(0);
- group = group.NestedGroup;
- }
- }
- internal void ResetGroupValue()
- {
- if (!string.IsNullOrEmpty(Condition))
- {
- groupValue = Report.Calc(Condition);
- }
- else
- {
- throw new GroupHeaderHasNoGroupCondition(Name);
- }
- }
- internal bool GroupValueChanged()
- {
- object value = null;
- if (!string.IsNullOrEmpty(Condition))
- {
- value = Report.Calc(Condition);
- }
- else
- {
- throw new GroupHeaderHasNoGroupCondition(Name);
- }
- if (groupValue == null)
- {
- if (value == null)
- return false;
- return true;
- }
- return !groupValue.Equals(value);
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="GroupHeaderBand"/> class with default settings.
- /// </summary>
- public GroupHeaderBand()
- {
- condition = "";
- sortOrder = SortOrder.Ascending;
- }
- }
- }
|