Import Designer Generated Report to App Guidance

3 posts, 1 answers
  1. Jaime Bula
    Jaime Bula avatar
    41 posts
    Member since:
    Apr 2009

    Posted 27 Aug 2012 Link to this post

    Hi,

    I've been looking everywhere, but I don't find any "Import Designer Generated Report to App Guidance".

    Should they be saved on the Database or DLL?, How to set the Data Source?, Best Practices? Security?? Etc...

    This info will be appreciatted.
  2. Answer
    erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 28 Aug 2012 Link to this post

    Hi Jaime

    Working on the same questions, this is what I came up so far:

    Using .trdx files directly in my App for simplicity (because I want Power Users to be able to design and use their own Reports):
    ReportDefinitionFile contains the path to the .trdx file. But you can store the report definition XML wherever you want. See the overloads to the Deserialize method.

    Not sure about subreports that are somewhere else than in files yet - you would probably have to implement your own ReportResolver.

    If you want to use .dlls there is no point in using the standalone designer use the Visual Studio Integrated Designer.
    I'm learning on this - so I don't know it this is best practice, but seems to work ;-)

    // use the telerik ReportXmlSerializer to create a Report object from XML
      var xmlSerializer = new ReportXmlSerializer();
      var reportDocument = (Telerik.Reporting.Report)xmlSerializer.Deserialize(ReportDefinitionFile);
     
      // create a ReportSource object
      var reportSource = new InstanceReportSource();
      reportSource.ReportDocument = reportDocument;
     
      // get the applications connection string (I'm using LLBLGEN here)
      SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
      scsb.ConnectionString = CommonDaoBase.ActualConnectionString;
     
      // ... needed by other parts ot the app
      this.connectionString = CommonDaoBase.ActualConnectionString;
      this.databaseDatabase = scsb.InitialCatalog;
      this.databaseServer = scsb.DataSource;
      this.databaseLogin = scsb.UserID;
      this.databasePassword = scsb.Password;
      this.integratedSecurity = scsb.IntegratedSecurity;
     
      // fill in well-known Report Parameters if the report defines them
      // if ReportParameter "OctopusConnectionString" is present, the report uses Binding to set up it's DataSource objects
      if (!SetReportParameters(reportDocument))
      {
          // no OctopusConnectionString Parameters, set the ConnectionString on the Report DataSource
          SqlDataSource sds = (SqlDataSource)reportDocument.DataSource;
          sds.ConnectionString = scsb.ConnectionString;
     
          // try to patch DataItems in the report (Table, Crosstab, List, Subreports have their own DataSource objects)
          SetConnectionStrings(reportDocument.Items, scsb.ConnectionString);
      }
     
      this.reportViewer1.ReportSource = reportSource;
      this.reportViewer1.RefreshReport();

    Fill In Report Parameters:
    Define standard Names for Parameters where your Reports expect Values or preset List of possible Values from your Application:
    The sample shows how to fill multi value parameters. Note that I set the Visible Attribute to false for Parameters that the User should not see (In the designer you have to set this to true to be able to fill in Values for Preview).

    I support two methods of dynamically changing the ConnectionString of the DataSources:
    If the report defines a Parameter called "OctopusConnectionString", I just fill that in. The report uses Binding (see old forum posts on examples) to set the DataSource.ConnectionString property from a Report Parameter.
    This allows the Report to use additional DataSources with other Connection Strings.

    private bool SetReportParameters(IReportDocument src)
       {
           bool connectionStringParameterDefined = false;
           foreach (ReportParameter p in src.ReportParameters)
           {
               if (p.Name == "OctopusOrganizations")
               {
                   DataTable dt = new DataTable();
                   dt.Columns.Add("Label", typeof(string));
                   dt.Columns.Add("Value", typeof(long));
     
                   System.Collections.Generic.List<long> allValues = new System.Collections.Generic.List<long>();
     
                   OrganizationCollection oc = new OrganizationCollection();
                   oc.GetMulti(null);
     
                   foreach (OrganizationEntity org in oc)
                   {
                       DataRow r = dt.NewRow();
                       r["Label"] = org.Name;
                       r["Value"] = org.Id;
                       allValues.Add(org.Id);
                       dt.Rows.Add(r);
                   }
     
                   p.Text = "Organizations";
                   p.AvailableValues.ValueMember = "Value";
                   p.AvailableValues.DisplayMember = "Label";
                   p.AvailableValues.DataSource = dt;
                   p.MultiValue = true;
     
                   if (Globals.ApplicationGlobals.ApplicationSettings.ReportAllOrganizations)
                   {
                       p.Visible = false;
                       p.Value = allValues;
                   }
                   else
                   {
                       p.Visible = true;
                   }
               }
               else if (p.Name == "OctopusSoftwareCategories")
               {
                   DataTable dt = new DataTable();
                   dt.Columns.Add("Label", typeof(string));
                   dt.Columns.Add("Value", typeof(long));
     
                   System.Collections.Generic.List<long> allValues = new System.Collections.Generic.List<long>();
     
                   SoftwareCategoryCollection scc = new SoftwareCategoryCollection();
                   scc.GetMulti(null);
     
                   foreach (SoftwareCategoryEntity sc in scc)
                   {
                       DataRow r = dt.NewRow();
                       r["Label"] = sc.Name;
                       r["Value"] = sc.Id;
                       allValues.Add(sc.Id);
                       dt.Rows.Add(r);
                   }
     
                   p.Text = "Software Categories";
                   p.AvailableValues.ValueMember = "Value";
                   p.AvailableValues.DisplayMember = "Label";
                   p.AvailableValues.DataSource = dt;
                   p.MultiValue = true;
     
                   if (Globals.ApplicationGlobals.ApplicationSettings.ReportAllSoftwareCategories)
                   {
                       p.Visible = false;
                       p.Value = allValues;
                   }
                   else
                   {
                       p.Visible = true;
                   }
               }
               else if (p.Name == "OctopusSoftwarePackages")
               {
                   DataTable dt = new DataTable();
                   dt.Columns.Add("Label", typeof(string));
                   dt.Columns.Add("Value", typeof(long));
     
                   System.Collections.Generic.List<long> allValues = new System.Collections.Generic.List<long>();
     
                   SoftwarePackageCollection spc = new SoftwarePackageCollection();
     
                   PredicateExpression filter = null;
                   filter = new PredicateExpression();
                   filter.Add(new FieldCompareValuePredicate(EntityFieldFactory.Create(SoftwareCategoryFieldIndex.Junk), ComparisonOperator.Equal, 0));
     
                   RelationCollection relations = new RelationCollection();
                   relations.Add(SoftwarePackageEntity.Relations.SoftwareCategoryEntityUsingSoftwareCategoryId);
     
                   spc.GetMulti(filter, relations);
     
                   foreach (SoftwarePackageEntity sp in spc)
                   {
                       DataRow r = dt.NewRow();
                       r["Label"] = sp.Name;
                       r["Value"] = sp.Id;
                       allValues.Add(sp.Id);
                       dt.Rows.Add(r);
                   }
     
                   p.Text = "Software Packages";
                   p.AvailableValues.ValueMember = "Value";
                   p.AvailableValues.DisplayMember = "Label";
                   p.AvailableValues.DataSource = dt;
                   p.MultiValue = true;
     
                   if (Globals.ApplicationGlobals.ApplicationSettings.ReportAllSoftwareCategories)
                   {
                       p.Visible = false;
                       p.Value = allValues;
                   }
                   else
                   {
                       p.Visible = true;
                   }
               }
               else if (p.Name == "OctopusReportName")
               {
                   p.Value = "Octopus " + this.ReportName;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusDatabase")
               {
                   p.Value = this.Database;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusLicensee")
               {
                   p.Value = this.LicenseeName;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusReportFile")
               {
                   p.Value = this.ReportDefinitionFile;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusObjectId")
               {
                   p.Value = this.ObjectId;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusRevision")
               {
                   p.Value = Octopus.Base.Licensing.OctopusVersion.BuildVersion;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusVersion")
               {
                   p.Value = Octopus.Base.Licensing.OctopusVersion.DisplayVersion;
                   p.Visible = false;
               }
               else if (p.Name == "OctopusConnectionString")
               {
                   p.Value = this.connectionString;
                   p.Visible = false;
                   connectionStringParameterDefined = true;
               }
           }
     
           return connectionStringParameterDefined;
       }


    If the report does not define a Parameter called "OctopusConnectionString", I set the Report.DataSource.ConnectionString property to my apps connection string.
    As other DataItems in the Report have their own DataSources, I have to recursively change the Connection String there too. This is where it gets a bit clumsy, see my other posts:

    /// <summary>
          /// Recursively set the connection string on all report items that have a sql datasource
          /// </summary>
          /// <param name="items"></param>
          /// <param name="connectionString"></param>
          private void SetConnectionStrings(Telerik.Reporting.ReportItemBase.ItemCollection items, string connectionString)
          {
              foreach (Telerik.Reporting.ReportItemBase ib in items)
              {
                  if (ib.Items != null)
                  {
                      if (ib.Items.Count > 0)
                      {
                          SetConnectionStrings(ib.Items, connectionString);
                      }
                  }
     
                  SqlDataSource ds = null;
     
                  if (ib is Telerik.Reporting.Chart)
                  {
                      Telerik.Reporting.Chart chart = ib as Telerik.Reporting.Chart;
                      ds = chart.DataSource as SqlDataSource;
                  }
                  else if (ib is Telerik.Reporting.Crosstab)
                  {
                      Telerik.Reporting.Crosstab crosstab = ib as Telerik.Reporting.Crosstab;
                      ds = crosstab.DataSource as SqlDataSource;
                  }
                  else if (ib is Telerik.Reporting.Table)
                  {
                      Telerik.Reporting.Table table = ib as Telerik.Reporting.Table;
                      ds = table.DataSource as SqlDataSource;
                  }
                  else if (ib is Telerik.Reporting.List)
                  {
                      Telerik.Reporting.List list = ib as Telerik.Reporting.List;
                      ds = list.DataSource as SqlDataSource;
                  }
                  else if (ib is Telerik.Reporting.SubReport)
                  {
                      Telerik.Reporting.SubReport rpt = ib as Telerik.Reporting.SubReport;
                      ds = rpt.Report.DataSource as SqlDataSource;
                  }
     
                  if (ds != null)
                  {
                      ds.ConnectionString = connectionString;
                  }
              }
          }

    Maybe someone at Telerik comes up with a more elegant solution to this.

    Regards
    Erwin


  3. DevCraft banner
  4. Jaime Bula
    Jaime Bula avatar
    41 posts
    Member since:
    Apr 2009

    Posted 28 Aug 2012 Link to this post

    Thanx for your post!

    Has pointed me on a direction. Now I'll try to make it work with the Silverlight Report Viewer.

    Best Regards!
Back to Top