最近在学习使用fastreport.studio,下载了一个试用版。安装后,我用vs2008打开它自带的demo程序--UserDataDemo。
发现有个问题,第一次点Bind .NET DataSet,然后看报表预览,没有问题,然后解除绑定,再点Bind .NET DataSet,再预览的时候就报错了。报的是“在位置10处没有任何行。”
我自己编写的程序,用了这个demo里面的FrxDataSet.cs和FrxDataTable.cs,也会出现这样的问题。无论怎么重置dataset,datatable都不能正常预览了,我把TfrxReportClass report也重建一次,还是不行。但是如果重新运行程序,就又可以正常的预览一次。第二次继续报错。这是mainform。
/// <summary>
/// {******************************************}
/// {                                          }
/// {             FastReport v3.0              }
/// {            .NET DataSet demo             }
/// {                                          }
/// {         Copyright (c) 1998-2005          }
/// {            Fast Reports Inc.             }
/// {                                          }
/// {******************************************}
/// </summary>using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using FastReport;namespace UserDataDemo
{
/// <summary>
/// Summary description for MainDemoForm.
/// </summary>
public class MainDemoForm : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
TfrxReportClass report;
FrxDataTable datatable;
FrxDataView dataview;
FrxDataSet dataset;
FrxArrayList arraylist; private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Random rnd;
private System.Windows.Forms.Button button4; private System.ComponentModel.Container components = null;

//
// Fills the demonstration dataset with sample data
//
private void FillTableWithSampleData(FrxDataTable datatable)
{
datatable.Columns.Add( "id", typeof(int) );
datatable.Columns.Add( "name", typeof(string) );
datatable.Columns.Add( "onemorename", typeof(string) );
// Add ten rows
for( int id=1; id<=10; id++ )
{
datatable.Rows.Add( 
new object[] { id, string.Format("customer {0}", id), string.Format("address {0}", 10-id) } 
);
}
datatable.AcceptChanges();
}
public MainDemoForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent(); rnd = new Random(); // Create report object
report = new TfrxReportClass(); // This object must appear in designer
arraylist = new FrxArrayList(); // Create the FR compatible DataTable object
datatable = new FrxDataTable("DataTableDemo");
FillTableWithSampleData(datatable); // Create the FR compatible DataView object
dataview = new FrxDataView(datatable, "DataViewDemo");
dataview.Sort = "onemorename ASC"; // We need following to make ongoing the report windows modal
report.MainWindowHandle = (int) this.Handle; // Load demmonstration report from file
report.LoadReportFromFile("..//..//.NET Data Demo.fr3"); report.ClearDatasets();
// Asiign datasets to report one more time
// beacuse theLoadReport... family functions breaks links between report and dataset
datatable.AssignToReport(true, report);
dataview.AssignToReport(true, report);

// Assigns DataTable to DataBand
datatable.AssignToDataBand("MasterData1", report);
// Assigns DataView to DataBand
dataview.AssignToDataBand("MasterData2", report);
} /// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null) 
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(72, 52);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(173, 26);
            this.button1.TabIndex = 0;
            this.button1.Text = "Show report";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(72, 17);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(173, 26);
            this.button2.TabIndex = 1;
            this.button2.Text = "Design report";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(72, 86);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(173, 26);
            this.button3.TabIndex = 2;
            this.button3.Text = "Bind .NET DataSet ";
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // button4
            // 
            this.button4.Enabled = false;
            this.button4.Location = new System.Drawing.Point(72, 121);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(173, 25);
            this.button4.TabIndex = 3;
            this.button4.Text = "Unbind .NET DataSet";
            this.button4.Click += new System.EventHandler(this.button4_Click);
            // 
            // MainDemoForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(322, 172);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "MainDemoForm";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.MainDemoForm_Load);
            this.ResumeLayout(false); }
#endregion /// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() 
{
Application.Run(new MainDemoForm());
} private void button1_Click(object sender, System.EventArgs e)
{
report.ShowReport();
} private void button2_Click(object sender, System.EventArgs e)
{
report.DesignReport();
} private void button3_Click(object sender, System.EventArgs e)
{
// Change buttons state
button3.Enabled = false;
button4.Enabled = true; // Create DataSet and load XML
dataset = new FrxDataSet();
dataset.ReadXml(@"..\..\DemoDataSet.xml"); // Find table in DataSet
DataTable table = dataset.Tables["Product"]; // Fill table with random data
for( int id=1; id<=10; id++ )
{
table.Rows.Add( 
new object[] { id, string.Format("product {0}", id * 3 / 2), rnd.Next(), 10-id } 
);
}
table.AcceptChanges(); // Make DataSet available in report
dataset.BindToReport(report);
dataset.BindTableToBand("Product", report, "MasterData3"); } private void button4_Click(object sender, System.EventArgs e)
{
// Change buttons state
button3.Enabled = true;
button4.Enabled = false; dataset.BindTableToBand(null, report, "MasterData3");
dataset.UnbindFromReport(report); System.GC.Collect();
}        private void MainDemoForm_Load(object sender, EventArgs e)
        {        }
}
}

解决方案 »

  1.   

    /// <summary>
    /// {******************************************}
    /// {                                          }
    /// {             FastReport v3.0              }
    /// {          .NET DataTable wrapper          }
    /// {                                          }
    /// {         Copyright (c) 1998-2006          }
    /// {            Fast Reports Inc.             }
    /// {                                          }
    /// {******************************************}
    /// </summary>using System;
    using System.Data;
    using System.ComponentModel;
    using FastReport;namespace UserDataDemo
    { public delegate void FrxOnFirst();
    public delegate void FrxOnNext();
    public delegate void FrxOnPrior();
    /// <summary>
    /// Summary description for FrxDataSet.
    /// </summary>
    public class FrxDataTable : DataTable
    {
    private int nItem;
    TfrxUserDataSetClass m_ds;
    private DataTable m_ChildTable; public new string TableName 
    {
    get { return m_ds.Name; }
    } public IfrxDataSet FrxTable
    {
    get { return m_ds as IfrxDataSet; }
    } public event FrxOnFirst FrxEventOnFirst;
    public event FrxOnNext FrxEventOnNext;
    public event FrxOnPrior FrxEventOnPrior; private void constructor(string name)
    {
    m_ChildTable = null;
    m_ds = new TfrxUserDataSetClass(); m_ds.Name = name; m_ds.OnCheckEOF += new IfrxUserDataSetEventDispatcher_OnCheckEOFEventHandler(OnCheckEOFEventHandler);
    m_ds.OnGetValue += new IfrxUserDataSetEventDispatcher_OnGetValueEventHandler(OnGetValueHandler);
    m_ds.OnFirst += new IfrxUserDataSetEventDispatcher_OnFirstEventHandler(OnFirstEventHandler);
    m_ds.OnNext += new IfrxUserDataSetEventDispatcher_OnNextEventHandler(OnNextEventHandler);
    m_ds.OnPrior += new IfrxUserDataSetEventDispatcher_OnPriorEventHandler(OnPriorEventHandler); DataColumnCollection cols = Columns;
    cols.CollectionChanged += new CollectionChangeEventHandler(ColumnsCollection_Changed);
    } public FrxDataTable(string name)
    {
    constructor(name);
    } public FrxDataTable(DataTable t)
    {
    constructor(t.TableName);
    string FieldNames = null;
    foreach (DataColumn col in t.Columns) FieldNames += col.Caption + "\n";
    m_ds.Fields = FieldNames;
    m_ChildTable = t;
    } /// <summary>
    /// Assigns table to report
    /// </summary>
    public void AssignToDataBand(string BandName, TfrxReportClass report)
    {
    IfrxComponent frx_component;
    frx_component = ((IfrxComponent) report).FindObject(BandName );
    ((IfrxDataBand) frx_component).DataSet =  (IfrxDataSet) m_ds;
    } /// <summary>
    /// Assigns table to report
    /// </summary>
    public void AssignToReport(bool Enable, TfrxReportClass report)
    {
    report.SelectDataset(Enable, m_ds as IfrxDataSet);
    } /// <summary>
    /// On First event handler
    /// </summary>
    private void OnFirstEventHandler() 
    {
    bool eof;
    nItem = 0; OnCheckEOFEventHandler(out eof); if ( ! eof && FrxEventOnFirst != null ) FrxEventOnFirst();
    } /// <summary>
    /// On Next event handler
    /// </summary>
    private void OnNextEventHandler()
    {
    bool eof; nItem++; OnCheckEOFEventHandler(out eof); if ( ! eof && FrxEventOnNext != null ) FrxEventOnNext();
    } /// <summary>
    /// On Prior evene handler
    /// </summary>
    private void OnPriorEventHandler()
    {
    bool eof; nItem--; OnCheckEOFEventHandler(out eof); if ( !eof && FrxEventOnPrior != null ) FrxEventOnPrior();
    } /// <summary>
    /// On check EndOfFile event handler
    /// </summary>
    private void OnCheckEOFEventHandler(out bool eof)
    {
    if(m_ChildTable == null) 
    {
    eof = (nItem >= Rows.Count); 
    }
    else
    {
    eof = (nItem >= m_ChildTable.Rows.Count);
    }
    } /// <summary>
    /// On get value handler
    /// </summary>
    public void OnGetValueHandler(object VarName, out object Val)
    {
    if(m_ChildTable == null) 
    {
    Val = Rows[nItem][VarName.ToString()];
    }
    else
    {
    Val = m_ChildTable.Rows[nItem][VarName.ToString()];
    }
    // FastReport does not know about System.Decimal object type
    // so convert it to Integer
    if ( Val is Decimal ) 
    {
    Val = Decimal.ToInt32( (Decimal) Val );
    }
    } /// <summary>
    /// Updates FastReport UserDataSet on Column addition
    /// </summary>
    private void ColumnsCollection_Changed(object sender, CollectionChangeEventArgs e)
    {
    DataColumnCollection cols = (DataColumnCollection) sender;
    string FieldNames = null;
    foreach (DataColumn col in cols) FieldNames += col.Caption + "\n";
    m_ds.Fields = FieldNames;
    }
    }
    }
    这是FrxDataTable的代码,我觉得问题就在这里。在我的程序里,每次调试到public void OnGetValueHandler(object VarName, out object Val)的时候,m_ChildTable 就会突变。变成上一次执行时候留下的datatable。
      

  2.   

    我遇到了调用AssignToReport出现HResult的问题