| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 | using System;using System.Collections.Generic;using System.ComponentModel;using FastReport.Utils;using FastReport.Data;using System.Drawing.Design;namespace FastReport{  /// <summary>  /// This class represents the Data band.  /// </summary>  /// <remarks>  /// Use the <see cref="DataSource"/> property to connect the band to a datasource. Set the  /// <see cref="Filter"/> property if you want to filter data rows. The <see cref="Sort"/>  /// property can be used to sort data rows.  /// </remarks>  public partial class DataBand : BandBase  {    #region Fields    private DataHeaderBand header;    private DataFooterBand footer;    private BandCollection bands;    private DataSourceBase dataSource;    private SortCollection sort;    private string filter;    private BandColumns columns;    private bool printIfDetailEmpty;    private bool printIfDatasourceEmpty;    private bool keepTogether;    private bool keepDetail;    private string idColumn;    private string parentIdColumn;    private float indent;    private bool keepSummary;    private Relation relation;    private bool collectChildRows;    private int rowCount;    private int maxRows;    private bool resetPageNumber;    #endregion    #region Properties    /// <summary>    /// Gets or sets a header band.    /// </summary>    [Browsable(false)]    public DataHeaderBand Header    {      get { return header; }      set      {        SetProp(header, value);        header = value;      }    }    /// <summary>    /// Gets a collection of detail bands.    /// </summary>    [Browsable(false)]    public BandCollection Bands    {      get { return bands; }    }    /// <summary>    /// Gets or sets a footer band.    /// </summary>    [Browsable(false)]    public DataFooterBand Footer    {      get { return footer; }      set      {        SetProp(footer, value);        footer = value;      }    }    /// <summary>    /// Gets or sets a data source.    /// Please note: data source have to be enabled.    /// </summary>    [Category("Data")]    public DataSourceBase DataSource    {      get      {        if (dataSource != null && !dataSource.Enabled)          return null;        return dataSource;      }      set      {        if (dataSource != value)        {          if (dataSource != null)            dataSource.Disposed -= new EventHandler(DataSource_Disposed);          if (value != null)            value.Disposed += new EventHandler(DataSource_Disposed);        }        dataSource = value;      }    }    /// <summary>    /// Gets or sets a number of rows in the virtual data source.    /// </summary>    /// <remarks>    /// Use this property if your data band is not connected to any data source. In this case    /// the virtual data source with the specified number of rows will be used.    /// </remarks>    [Category("Data")]    [DefaultValue(1)]    public int RowCount    {      get { return rowCount; }      set { rowCount = value; }    }    /// <summary>    /// Limits the maximum number of rows in a datasource. 0 means no limit.    /// </summary>    [Category("Data")]    [DefaultValue(0)]    public int MaxRows    {      get { return maxRows; }      set { maxRows = value; }    }    /// <summary>    /// Gets or sets a relation used to establish a master-detail relationship between    /// this band and its parent.    /// </summary>    /// <remarks>    /// Use this property if there are several relations exist between two data sources.    /// If there is only one relation (in most cases it is), you can leave this property empty.    /// </remarks>    [Category("Data")]    [Editor("FastReport.TypeEditors.RelationEditor, FastReport", typeof(UITypeEditor))]    public Relation Relation    {      get { return relation; }      set { relation = value; }    }    /// <summary>    /// Gets the collection of sort conditions.    /// </summary>    [Browsable(false)]    public SortCollection Sort    {      get { return sort; }    }    /// <summary>    /// Gets the row filter expression.    /// </summary>    /// <remarks>    /// This property can contain any valid boolean expression. If the expression returns <b>false</b>,    /// the corresponding data row will not be printed.    /// </remarks>    [Category("Data")]    [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))]    public string Filter    {      get { return filter; }      set { filter = value; }    }    /// <summary>    /// Gets the band columns.    /// </summary>    [Category("Appearance")]    [Editor("FastReport.TypeEditors.DataBandColumnEditor, FastReport", typeof(UITypeEditor))]    public BandColumns Columns    {      get { return columns; }    }    /// <summary>    /// Gets or sets a value that determines whether to print a band if all its detail rows are empty.    /// </summary>    [DefaultValue(false)]    [Category("Behavior")]    public bool PrintIfDetailEmpty    {      get { return printIfDetailEmpty; }      set { printIfDetailEmpty = value; }    }    /// <summary>    /// Gets or sets a value that determines whether to print a band if its datasource is empty.    /// </summary>    [DefaultValue(false)]    [Category("Behavior")]    public bool PrintIfDatasourceEmpty    {      get { return printIfDatasourceEmpty; }      set { printIfDatasourceEmpty = value; }    }    /// <summary>    /// Gets or sets a value indicating that all band rows 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 indicating that the band should be printed together with all its detail rows.    /// </summary>    [DefaultValue(false)]    [Category("Behavior")]    public bool KeepDetail    {      get { return keepDetail; }      set { keepDetail = value; }    }    /// <summary>    /// Gets or sets the key column that identifies the data row.    /// </summary>    /// <remarks>    /// <para>This property is used when printing a hierarchic list.</para>    /// <para>To print the hierarchic list, you have to setup three properties: <b>IdColumn</b>,    /// <b>ParentIdColumn</b> and <b>Indent</b>. First two properties are used to identify the data    /// row and its parent; the <b>Indent</b> property specifies the indent that will be used to shift    /// the databand according to its hierarchy level.</para>    /// <para/>When printing hierarchy, FastReport shifts the band to the right    /// (by value specified in the <see cref="Indent"/> property), and also decreases the    /// width of the band by the same value. You may use the <b>Anchor</b> property of the    /// objects on a band to indicate whether the object should move with the band, or stay    /// on its original position, or shrink.    /// </remarks>    [Category("Hierarchy")]    [Editor("FastReport.TypeEditors.DataColumnEditor, FastReport", typeof(UITypeEditor))]    public string IdColumn    {      get { return idColumn; }      set { idColumn = value; }    }    /// <summary>    /// Gets or sets the column that identifies the parent data row.    /// </summary>    /// <remarks>    /// This property is used when printing a hierarchic list. See description of the    /// <see cref="IdColumn"/> property for more details.    /// </remarks>    [Category("Hierarchy")]    [Editor("FastReport.TypeEditors.DataColumnEditor, FastReport", typeof(UITypeEditor))]    public string ParentIdColumn    {      get { return parentIdColumn; }      set { parentIdColumn = value; }    }    /// <summary>    /// Gets or sets the indent that will be used to shift the databand according to its hierarchy level.    /// </summary>    /// <remarks>    /// This property is used when printing a hierarchic list. See description of the    /// <see cref="IdColumn"/> property for more details.    /// </remarks>    [DefaultValue(37.8f)]    [Category("Hierarchy")]    [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]    public float Indent    {      get { return indent; }      set { indent = value; }    }    /// <summary>    /// Gets or sets a value indicating that the databand should collect child data rows.    /// </summary>    /// <remarks>    /// This property determines how the master-detail report is printed. Default behavior is:    /// <para/>MasterData row1    /// <para/>-- DetailData row1    /// <para/>-- DetailData row2    /// <para/>-- DetailData row3    /// <para/>MasterData row2    /// <para/>-- DetailData row1    /// <para/>-- DetailData row2    /// <para/>When you set this property to <b>true</b>, the master databand will collect all child data rows    /// under a single master data row:    /// <para/>MasterData row1    /// <para/>-- DetailData row1    /// <para/>-- DetailData row2    /// <para/>-- DetailData row3    /// <para/>-- DetailData row4    /// <para/>-- DetailData row5    /// </remarks>    [DefaultValue(false)]    [Category("Behavior")]    public bool CollectChildRows    {      get { return collectChildRows; }      set { collectChildRows = value; }    }    /// <summary>    /// Gets or sets a value that determines whether to reset the page numbers when this band 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 bool IsDeepmostDataBand    {      get { return Bands.Count == 0; }    }    internal bool KeepSummary    {      get { return keepSummary; }      set { keepSummary = value; }    }    internal bool IsHierarchical    {      get      {        return !String.IsNullOrEmpty(IdColumn) && !String.IsNullOrEmpty(ParentIdColumn);      }    }    internal bool IsDatasourceEmpty    {      get { return DataSource == null || DataSource.RowCount == 0; }    }    #endregion    #region Private Methods    private void DataSource_Disposed(object sender, EventArgs e)    {      dataSource = null;    }    #endregion    #region Protected Methods    /// <inheritdoc/>    protected override void DeserializeSubItems(FRReader reader)    {      if (String.Compare(reader.ItemName, "Sort", true) == 0)        reader.Read(Sort);      else        base.DeserializeSubItems(reader);    }    #endregion    #region IParent    /// <inheritdoc/>    public override void GetChildObjects(ObjectCollection list)    {      base.GetChildObjects(list);      if (IsRunning)        return;      list.Add(header);      foreach (BandBase band in bands)      {        list.Add(band);      }      list.Add(footer);    }    /// <inheritdoc/>    public override bool CanContain(Base child)    {      return base.CanContain(child) || (child is DataHeaderBand || child is DataFooterBand ||        child is DataBand || child is GroupHeaderBand);    }    /// <inheritdoc/>    public override void AddChild(Base child)    {      if (IsRunning)      {        base.AddChild(child);        return;      }      if (child is DataHeaderBand)        Header = child as DataHeaderBand;      else if (child is DataFooterBand)        Footer = child as DataFooterBand;      else if (child is DataBand || child is GroupHeaderBand)        bands.Add(child as BandBase);      else        base.AddChild(child);    }    /// <inheritdoc/>    public override void RemoveChild(Base child)    {      base.RemoveChild(child);      if (IsRunning)        return;      if (child is DataHeaderBand && header == child as DataHeaderBand)        Header = null;      if (child is DataFooterBand && footer == child as DataFooterBand)        Footer = null;      if (child is DataBand || child is GroupHeaderBand)        bands.Remove(child as BandBase);    }    /// <inheritdoc/>    public override int GetChildOrder(Base child)    {      if (child is BandBase && !IsRunning)        return bands.IndexOf(child as BandBase);      return base.GetChildOrder(child);    }    /// <inheritdoc/>    public override void SetChildOrder(Base child, int order)    {      if (child is BandBase && !IsRunning)      {        if (order > bands.Count)          order = bands.Count;        int oldOrder = child.ZOrder;        if (oldOrder != -1 && order != -1 && oldOrder != order)        {          if (oldOrder <= order)            order--;          bands.Remove(child as BandBase);          bands.Insert(order, child as BandBase);        }      }      else        base.SetChildOrder(child, order);    }    #endregion    #region Public Methods    /// <inheritdoc/>    public override void Assign(Base source)    {      base.Assign(source);      DataBand src = source as DataBand;      DataSource = src.DataSource;      RowCount = src.RowCount;      MaxRows = src.MaxRows;      Relation = src.Relation;      Sort.Assign(src.Sort);      Filter = src.Filter;      Columns.Assign(src.Columns);      PrintIfDetailEmpty = src.PrintIfDetailEmpty;      PrintIfDatasourceEmpty = src.PrintIfDatasourceEmpty;      KeepTogether = src.KeepTogether;      KeepDetail = src.KeepDetail;      IdColumn = src.IdColumn;      ParentIdColumn = src.ParentIdColumn;      Indent = src.Indent;      CollectChildRows = src.CollectChildRows;      ResetPageNumber = src.ResetPageNumber;    }    internal override void UpdateWidth()    {      if (Columns.Count > 1)      {        Width = Columns.ActualWidth;      }      else if (!String.IsNullOrEmpty(IdColumn) && !String.IsNullOrEmpty(ParentIdColumn))      {        if (PageWidth != 0)          Width = PageWidth - Left;      }      else        base.UpdateWidth();    }    /// <inheritdoc/>    public override void Serialize(FRWriter writer)    {      DataBand c = writer.DiffObject as DataBand;      base.Serialize(writer);      if (writer.SerializeTo == SerializeTo.Preview)        return;      if (DataSource != c.DataSource)        writer.WriteRef("DataSource", DataSource);      if (RowCount != c.RowCount)        writer.WriteInt("RowCount", RowCount);      if (MaxRows != c.MaxRows)        writer.WriteInt("MaxRows", MaxRows);      if (Relation != c.Relation)        writer.WriteRef("Relation", Relation);      if (Sort.Count > 0)        writer.Write(Sort);      if (Filter != c.Filter)        writer.WriteStr("Filter", Filter);      Columns.Serialize(writer, c.Columns);      if (PrintIfDetailEmpty != c.PrintIfDetailEmpty)        writer.WriteBool("PrintIfDetailEmpty", PrintIfDetailEmpty);      if (PrintIfDatasourceEmpty != c.PrintIfDatasourceEmpty)        writer.WriteBool("PrintIfDatasourceEmpty", PrintIfDatasourceEmpty);      if (KeepTogether != c.KeepTogether)        writer.WriteBool("KeepTogether", KeepTogether);      if (KeepDetail != c.KeepDetail)        writer.WriteBool("KeepDetail", KeepDetail);      if (IdColumn != c.IdColumn)        writer.WriteStr("IdColumn", IdColumn);      if (ParentIdColumn != c.ParentIdColumn)        writer.WriteStr("ParentIdColumn", ParentIdColumn);      if (FloatDiff(Indent, c.Indent))        writer.WriteFloat("Indent", Indent);      if (CollectChildRows != c.CollectChildRows)        writer.WriteBool("CollectChildRows", CollectChildRows);      if (ResetPageNumber != c.ResetPageNumber)        writer.WriteBool("ResetPageNumber", ResetPageNumber);    }    /// <inheritdoc/>    public override string[] GetExpressions()    {      List<string> list = new List<string>();      foreach (Sort sort in Sort)      {        list.Add(sort.Expression);      }      list.Add(Filter);      return list.ToArray();    }    /// <summary>    /// Initializes the data source connected to this band.    /// </summary>    public void InitDataSource()    {      if (DataSource == null)      {        DataSource = new VirtualDataSource();        DataSource.SetReport(Report);      }      if (DataSource is VirtualDataSource)        (DataSource as VirtualDataSource).VirtualRowsCount = RowCount;      DataSourceBase parentDataSource = ParentDataBand == null ? null : ParentDataBand.DataSource;      bool collectChildRows = ParentDataBand == null ? false : ParentDataBand.CollectChildRows;      if (Relation != null)        DataSource.Init(Relation, Filter, Sort, collectChildRows);      else        DataSource.Init(parentDataSource, Filter, Sort, collectChildRows);    }    internal bool IsDetailEmpty()    {      if (PrintIfDetailEmpty || Bands.Count == 0)        return false;      foreach (BandBase band in Bands)      {        if (!band.IsEmpty())          return false;      }      return true;    }    internal override bool IsEmpty()    {      InitDataSource();      if (IsDatasourceEmpty)        return !PrintIfDatasourceEmpty;      DataSource.First();      while (DataSource.HasMoreRows)      {        if (!IsDetailEmpty())          return false;        DataSource.Next();      }      return true;    }    /// <inheritdoc/>    public override void InitializeComponent()    {      base.InitializeComponent();      KeepSummary = false;    }    #endregion    /// <summary>    /// Initializes a new instance of the <see cref="DataBand"/> class.    /// </summary>    public DataBand()    {      bands = new BandCollection(this);      sort = new SortCollection();      filter = "";      columns = new BandColumns(this);      idColumn = "";      parentIdColumn = "";      indent = 37.8f;      rowCount = 1;      SetFlags(Flags.HasSmartTag, true);    }  }}
 |