在报表系统中,我们通常会有这样的需求,就是由用户来决定报表中需要显示的数据,比如数据源中共有八列数据,用户可以自己选择在报表中显示哪些列,并且能够自动调整列的宽度,已铺满整个页面。本文就讲解一下ActiveReports中该功能的实现方法。
第一步:设计包含所有列的报表模板,将数据源中的所有列先放置到报表设计界面,并设置你需要的列宽,最终界面如下:
第二步:在报表的后台代码中添加一个Columns的属性,用于接收用户选择的列,同时,在报表的ReportStart事件中添加以下代码:
/// <summary>
/// 用户选择的列名称
/// </summary>
public List<string> Columns;
private void Report1_ReportStart(object sender, EventArgs e)
{
// 定义临时变量
int count = 0;
float width = 0;
Label tmp = null;
// 列头控件
List<Label> headers = new List<Label>();
headers.Add(this.label1);
headers.Add(this.label2);
headers.Add(this.label3);
headers.Add(this.label4);
headers.Add(this.label5);
headers.Add(this.label6);
headers.Add(this.label7);
headers.Add(this.label8);
// 数据控件
List<TextBox> cols = new List<TextBox>();
cols.Add(this.textBox1);
cols.Add(this.textBox2);
cols.Add(this.textBox3);
cols.Add(this.textBox4);
cols.Add(this.textBox5);
cols.Add(this.textBox6);
cols.Add(this.textBox7);
cols.Add(this.textBox8);
List<CrossSectionLine> lines = new List<CrossSectionLine>();
lines.Add(crossSectionLine1);
lines.Add(crossSectionLine2);
lines.Add(crossSectionLine3);
lines.Add(crossSectionLine4);
lines.Add(crossSectionLine5);
lines.Add(crossSectionLine6);
lines.Add(crossSectionLine7);
// 隐藏不需要显示的控件,并计算需要显示控件的总宽度
for (int c = 0; c < cols.Count; c++)
{
if (!Columns.Contains(cols[c].DataField))
{
headers[c].Visible = false;
cols[c].Visible = false;
if (c < cols.Count - 1)
{
lines[c].Visible = false;
}
}
else
{
width += headers[c].Width;
}
}
// 调整列的位置以及宽度
for (int c = 0; c < cols.Count; c++)
{
// 隐藏控件不需要处理
if (cols[c].Visible == false)
{
continue;
}
headers[c].Width = headers[c].Width * (this.PrintWidth / width);
cols[c].Width = headers[c].Width;
// 设置控件坐标
if (tmp == null)
{
// 设置需要显示的第一列坐标
headers[c].Location = new PointF(0, headers[c].Location.Y);
cols[c].Location = new PointF(headers[c].Location.X, cols[c].Location.Y);
}
else
{
// 设置需要显示的非第一列坐标,应该为前一列坐标加上宽度
headers[c].Location = new PointF(tmp.Location.X + tmp.Width, headers[c].Location.Y);
cols[c].Location = new PointF(headers[c].Location.X, cols[c].Location.Y);
}
// 调整边线位置
if (c < headers.Count - 1)
{
lines[c].Start = new PointF(headers[c].Location.X + headers[c].Width, lines[c].Start.Y);
lines[c].End = lines[c].Start;
}
count += 1;
tmp = headers[c];
}
}
第三步:运行报表,在运行报表之前需要指定用户选择的列:
源码下载: