本文为实现在水晶报表中显示任意列,并且无论显示多少列,要保持列宽总和不变,即当显示的列数比较少时,不能让其“缩”在左侧,而导致右侧一片放空,就是要实现根据列数的多少让其具有“自动拉伸”的效果。
本文实现的效果是显示3~8列,望能给各位起到一定的参考作用:
因最多显示8列,故先在模板放置8个字段对象
模板看似简单,但它对尺寸的控制要求很高,不仅每个对象大小要保持一样,并且对对象间的间距控制也半点马虎不得,比如这里每个对象的宽度为1353,列1的Left属性为105,所以列2的Left属性=105+1353+40=1498,列3的Left属性=1498+1353+40……依此类推得其余列的Left属性值,中间的40是对象边框的宽度。这边模板的精确设计是为了获得 列宽总和,因为这个列宽总和始终保持不变,无论当前显示多少列
最少显示3列,故对后面五列设置抑制显示,当然要加上抑制显示条件,其中有一个参数字段OptionNum,表示当前要显示的总列数
模板就是这样,我们再来看看关键代码段,本文最最关键的正是如何动态控制对象的尺寸并以此来达到“自动拉伸”的效果
//由于列宽总和要保持一致,故需先获取总宽度
int tableWidth = 1353 * 8 + 7 * 40; //1353为对象宽度,40为边框宽度
//设置当前每一列的宽度,必须先减掉中间边框的宽度再均分
int columnWidth = (tableWidth - (N - 1) * 40) / N;
//标识 列序号
int columnOrder = 1;
//遍历详细节的对象
foreach (ReportObject obj in ((CrystalReport1)myReport).Section3.ReportObjects)
{
//列1的Left属性(105)保持不变
obj.Left = 105 + (columnWidth + 40) * (columnOrder - 1);
obj.Width = columnWidth;
columnOrder++;
}
}
/// <summary>
/// 全局水晶报表对象
/// </summary>
ReportDocument myReport;
/// <summary>
/// 窗体关闭后立即删除水晶报表产生的临时文件,避免过多临时文件从而导致“报表加载失败”
/// </summary>
private void rptForm_FormClosing(object sender, FormClosingEventArgs e)
{
myReport.Dispose();
}
/// <summary>
/// 填充水晶报表“骨架”并为水晶报表设定数据源
/// </summary>
private void rptForm_Load(object sender, EventArgs e)
{
//往数据集“塞”测试数据
myDataSet.MultipleColTable.AddMultipleColTableRow("行一", "行一", "行一", "行一", "行一", "行一", "行一", "行一");
myDataSet.MultipleColTable.AddMultipleColTableRow("行二", "行二", "行二", "行二", "行二", "行二", "行二", "行二");
myDataSet.MultipleColTable.AddMultipleColTableRow("行三", "行三", "行三", "行三", "行三", "行三", "行三", "行三");
myDataSet.MultipleColTable.AddMultipleColTableRow("行四", "行四", "行四", "行四", "行四", "行四", "行四", "行四");
myDataSet.MultipleColTable.AddMultipleColTableRow("行五", "行五", "行五", "行五", "行五", "行五", "行五", "行五");
myReport = new CrystalReport1();
myReport.SetDataSource(myDataSet);
}
最后的效果图