Access Report Controls Using Reflection


One of the reasons why ActiveReports 8 is one of the most popular reporting tools is due to the flexibility which is offers to the developers. Relying on .NET framework as its base, it can be moulded according to the user's requirements and allows almost endless customizations. When we talk about designing reports we work with report controls which can be used to create different layouts. If we wish to make any changes to the control then creating a report object and accessing the control directly sounds pretty simple and indeed it is. However at times there might be a situation where the user knows the control name and wants to access it on the report just using its name. What next? Well fortunately .NET framework provides a powerful way to tackle such situations and its name is Reflection. So it is time to bring it into the picture. As the MSDN article states: "Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties."


Since we only have the control name available to us we will use reflection to get the control type and make changes to it as required. Let me show a simple image so that the things I have discussed makes more sense. In this example, I am allowing users to enter the textbox name and the text they want to update in it. Once they do it and click the button, the specified control is updated with the new text. Moreover this example allows you to do it for both Section Based Reports as well as Page Based Reports. ReflectionForm


Since we now have some idea about what we are talking about, it makes sense to see how to go ahead and implement it. Let us start with Section Based Reports.

Section Based Reports Implementation

Since the Section Based Reports are event driven, the required code can be written within the report class itself. Since in this example, we are passing values from the form, we create two public properties inside the form class to hold the control name and its text. This is how the code inside form looks like:

  • Code Inside the Form:

     public static string sectionControlName { get; set; }  
     public static string sectionControlText { get; set; }private void btnSection_Click(object sender, EventArgs e)  
        sectionControlName = txtSectionControlName.Text;  
        sectionControlText = txtSectionControlText.Text;  
        SectionReport1 sectionReport = new SectionReport1();  
  • Code Inside Section Report

    public GrapeCity.ActiveReports.SectionReportModel.ARControl GetSectionControlByName(string Name)  
        System.Reflection.FieldInfo info = this.GetType().GetField(Name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.IgnoreCase);  
        if (info == null)  
           return null;  
        object o = info.GetValue(this);  
        return (GrapeCity.ActiveReports.SectionReportModel.ARControl)o;  
     private void detail_Format(object sender, EventArgs e)  
        if (Form1.sectionControlName != "" || Form1.sectionControlText != "")  
           GrapeCity.ActiveReports.SectionReportModel.ARControl t = GetSectionControlByName(Form1.sectionControlName);  
           ((GrapeCity.ActiveReports.SectionReportModel.TextBox)t).Text = Form1.sectionControlText;  
           ((GrapeCity.ActiveReports.SectionReportModel.TextBox)t).ForeColor = Color.Gray;  

Page Based Reports Implementation

Since unlike Section Based Reports, the Page Based Reports are not event driven, we will write all the related code and the method which uses reflection in the form class itself. This is how it looks:

  • Code Inside the Form

    GrapeCity.ActiveReports.PageReport pageReport;  
    private void btnPage_Click(object sender, EventArgs e)  
       string file_name = @"..\\..\\PageReport1.rdlx";  
       pageReport = new GrapeCity.ActiveReports.PageReport(new System.IO.FileInfo(file_name));  
       if (txtPageControlName.Text != "" || txtPageControlText.Text != "")  
          GetPageControlByName(txtPageControlName.Text).Value = txtPageControlText.Text;  
          GetPageControlByName(txtPageControlName.Text).Style.Color = GrapeCity.ActiveReports.Expressions.ExpressionInfo.FromString("Red");  
       GrapeCity.ActiveReports.Document.PageDocument pageDocument = new GrapeCity.ActiveReports.Document.PageDocument(pageReport);  
    #region Page Report Reflection Function  
    GrapeCity.ActiveReports.PageReportModel.TextBox reportItem;  
    public GrapeCity.ActiveReports.PageReportModel.TextBox GetPageControlByName(string Name)  
       object obj = pageReport.Report.Body.Components;  
       FieldInfo[] fieldInfos = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.InvokeMethod);  
       dynamic repItems = fieldInfos[0].GetValue(obj);  
       var count = ((ICollection)repItems).Count;  
       for (int i = 0; i < count; i++)  
          if (repItems[i].Name == Name)  
             reportItem = repItems[i];  
       return reportItem;  

See It Yourself!!

So it isn't difficult to access any control on the report directly as Reflection make it simple. However you can download the sample application using the download icon below. Also the GIF image below should help in getting a better understanding of the sample. FinalOutput


GrapeCity Developer Tools
comments powered by Disqus