WPF中RDLC报表的钻取实现

1、新建wpf项目,并引入3个程序集:

Microsoft.ReportViewer.WinForms

WindowsFormsIntegration

System.Windows.Forms

如果无法搜索到,可能是VS没有安装相关组件,请如图添加:

 

2、新建Entities文件夹,在其中添加Entities.cs文件,其中创建两个实体类,Department和Employee

class Department
    {
        public int DepartmentId { get; set; }
        public string DepartmentName { get; set; }
        public string DepartmentInfo { get; set; }
    }

    class Employee
    {
        public int EmployeeId { get; set; }
        public int DepartmentId { get; set; }
        public string Name { get; set; }
        public string NickName { get; set; }
    }
View Code

 

3、创建钻取表——部门表Department.rdlc,内部控件可在工具箱窗口创建:

  3.1、绑定数据集/源,在Report Data中的数据集项目右键-添加数据集(名称为:DepartmentDS)-新建数据源-对象,下一步选择sep2中建立的Department对象。

  3.2、完成后即可将数据源的字段添加如报表中。

  3.3、在DepartmentId中右键-文本框属性-操作-选择“转到报表”,指定报表填入“Emploee”(此报表下一步创建)参数填入DepartmentId:

  

  再设置一下钻取关键字的字体样式,钻取表配置完成。

4、创建目标表——员工表Employee:

  4.1、添加绑定Employee对象,操作如部门表,数据集名称指定为:(名称为:EmployeeDS)。

  4.2、定义参数,Report Data窗口中:参数右键-添加参数,名称填入DepartmentId,类型为Integer(要与传入类型一致)。

  4.3、添加筛选器,筛选器可以采用指定参数来自动过滤数据,选择数据集所在行右键-tablix属性-筛选器-点击fx进入表达式编写。

  其中表达式填入:=CInt(Fields!DepartmentId.Value)类型为Integer,运算符为“=”,值填入:=CInt(Parameters!DepartmentId.Value)

  到此,报表主要设计完成。

5、在MainWindow窗体中放入ReportViewer:

  5.1、xaml窗口代码,先引入命名空间:xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms" 

  然后主体部分:

  

    <Grid>
        <WindowsFormsHost>
            <rv:ReportViewer x:Name="reportViewer"/>
        </WindowsFormsHost>
    </Grid>
View Code

  5.2、窗口交互代码,功能是为报表填充数据,数据介质是DataTable,内容正是对应的实体类。

  

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += DepartmentLoaded;
            //this.Loaded += EmployeeLoaded;
        }

        // 载入部门报表
        private void DepartmentLoaded(object sender, RoutedEventArgs e)
        {
            // 模拟一个DataTable
            DataTable dt = new DataTable();
            dt.Columns.Add("DepartmentId", typeof(int));
            dt.Columns.Add("DepartmentName", typeof(string));
            dt.Columns.Add("DepartmentInfo", typeof(string));

            dt.Rows.Add(123, "内勤", "B3456123");
            dt.Rows.Add(234, "外勤", "U3884912");

            ReportDataSource reportDataSource = new ReportDataSource();

            reportDataSource.Name = "DepartmentDS";
            reportDataSource.Value = dt;

            reportViewer.Reset();

            reportViewer.LocalReport.ReportPath = Directory.GetCurrentDirectory() + "\\Department.rdlc";
            reportViewer.LocalReport.DataSources.Add(reportDataSource);
            reportViewer.Drillthrough += new DrillthroughEventHandler(report_Drillthrough);// 处理钻取事件

            reportViewer.RefreshReport();
        }


        // 载入员工报表
        private void EmployeeLoaded(object sender, RoutedEventArgs e)
        {
            // 模拟一个DataTable
            DataTable dt = MakeEmployeeDT();

            ReportDataSource reportDataSource = new ReportDataSource();

            reportDataSource.Name = "EmployeeDS";
            reportDataSource.Value = dt;

            reportViewer.Reset();

            reportViewer.LocalReport.ReportPath = Directory.GetCurrentDirectory() + "\\Employee.rdlc";
            reportViewer.LocalReport.DataSources.Add(reportDataSource);

            ReportParameter departmentId = new ReportParameter("DepartmentId", "1");
            reportViewer.LocalReport.SetParameters((new ReportParameter[] { departmentId }));// 放入参数测试

            reportViewer.RefreshReport();
        }

        // 填充钻取的数据
        private void report_Drillthrough(object sender, DrillthroughEventArgs e)
        {
            int dId = 0;
            DataTable dt = MakeEmployeeDT();

            ReportDataSource reportDataSource = new ReportDataSource();

            reportDataSource.Name = "EmployeeDS";
            reportDataSource.Value = dt;

            Report newRV = e.Report;

            if (newRV.GetParameters().Count > 0 && newRV.GetParameters()["DepartmentId"] != null)
            {
                string tmp = newRV.GetParameters()["DepartmentId"].Values[0].Trim();
                dId = Int32.Parse(tmp, 0);
            }
            LocalReport localReport = (LocalReport)e.Report;
            localReport.DataSources.Add(reportDataSource);

            //reportViewer.RefreshReport();// 钻取操作不能refresh,否则会导致刷新窗口,清除钻取记录
        }

        // 创建员工数据表
        private DataTable MakeEmployeeDT()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("EmployeeId", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("NickName", typeof(string));
            dt.Columns.Add("DepartmentId", typeof(string));

            dt.Rows.Add(001, "张三", "John", 123);
            dt.Rows.Add(002, "李四", "Joo", 234);
            return dt;
        }

    }
View Code

 

总结/说明:

  1、本例使用实体对象作为绑定数据源,可以较好的整合进当前项目,维持现有架构的层级关系,另外也可直接配置数据库或WCF服务,请自行测试;

  2、新建数据源时若找不到step2建立的实体类,请重新编译项目

  3、初次接触者RDLC文件的xml源码图形化的布局设计都定义在里面。

  4、钻取目标表的结构结果筛选即可由rdlc定义完成,也可以获取参数后自行组装DataTable,前者简单省事,后者性能高一些,看需求~。

 

最后,贴一张运行效果图:

 

 

程序打包下载

 

posted @ 2016-09-26 17:03  好人卡收藏家  阅读(2741)  评论(0编辑  收藏  举报