如何检测代码是否在设计时执行?

时间:2016-03-24 08:36:46

标签: .net activereports

Visual Studio的ActiveReports 10扩展程序具有报表设计器 设计器窗口包含选项卡" Preview"可以在不运行整个应用程序的情况下查看设计器报告

我想创造"测试"仅在设计时使用的数据 在代码中设置数据工作正常。

Private Sub TestReport_ReportStart(sender As Object, e As EventArgs) Handles Me.ReportStart
  Me.DataSource = TestModule.GetData() ' - Test data
  'Me.DataSource = _MyDataService.GetData() ' - Production data
End Sub

但在处理报告后,您需要记住删除测试数据并设置"生产"代码,很容易被遗忘。

似乎"预览" - 代码在运行时模式下执行,请参阅下面使用的测试代码

Private Sub TestReport_ReportStart(sender As Object, e As EventArgs) Handles Me.ReportStart
    Dim isDebug As Boolean = System.Diagnostics.Debugger.IsAttached 'Return false
    Dim mode As LicenseUsageMode = LicenseManager.UsageMode 'Return Runtime       
End Sub

3 个答案:

答案 0 :(得分:1)

感谢您使用activereports。

目前,我不知道如何在AR10中这样做。您可以使用应用程序中的config参数来控制它,类似于isDebug设置,但使用的是XML配置。

另外,请发送电子邮件给我们的支持小组http://activereports.grapecity.com,我们可以在将来的更新中添加设计时报告变量,您可以在代码和查询中查看。

答案 1 :(得分:0)

经过一些阅读和测试后,我想出了两个针对该问题的解决方案。

解决方案1 ​​ - Assembly.GetEntryAssembly()
来自MSDN:

  

获取默认应用程序域中的进程可执行文件。在   其他应用程序域,这是第一个可执行文件   由AppDomain.ExecuteAssembly执行。

似乎"预览"未在默认应用程序域中运行且ActiveReports未调用AppDomain.ExecuteAssembly()。因此方法Assembly.GetEntryAssembly()将返回null

Public Class TestReport

    Private _DataService As IDataService

    Public Sub New(dataService As IDataService)
        Me.InitializeComponent()
        _DataService = dataService
    End Sub

    Private Sub Me_ReportStart(sender As Object, e As EventArgs) Handles Me.ReportStart
        If Me.IsDesignMode = True Then
            Me.DataSource = TestModule.GetData()
        Else
            Me.DataSource = _DataService.GetData()
        End If
    End Sub

    Protected ReadOnly Property IsDesignMode As Boolean
        Get
            Return Assembly.GetEntryAssembly() Is Nothing
        End Get
    End Property

End Class

解决方案2 - 无参数构造函数
- 报告类使用界面IDataService获取数据 - 创建返回测试数据的IDataService的实现 - 创建无参数构造函数,其中将使用接口的测试实现实例作为参数调用带有IDataService实例的原始构造函数。
- 使用Obsolete属性标记无参数构造函数,以告知其他开发人员不使用它 - 可选:在此使用第一个解决方案,如果测试数据服务在运行时使用

,则抛出异常
Public Class TestReport

    Private _DataService As IDataService

    Public Sub New(dataService As IDataService)
        Me.InitializeComponent()
        _DataService = dataService
    End Sub

    <Obsolete("Parameterless consrtuctor only for designer usage.")>
    Public Sub New()
        MyClass.New(New TestDataService())
    End Sub

    Private Sub Me_ReportStart(sender As Object, e As EventArgs) Handles Me.ReportStart
        Me.DataSource = _DataService.GetData()
    End Sub

End Class

Public Class TestDataService
    Implements IDataService

    Public Sub New()
        If Assembly.GetEntryAssembly() IsNot Nothing Then
            Throw New InvalidOperationException("Service cannot be used in run-time")
        End If
    End Sub

    Public Function GetData() As List(Of CustomItem) Implements IDataService.GetData
        'Generate test data
    End Function
End Class

答案 2 :(得分:0)

法比奥,我玩弄了这个。

我发现LicenseUsageMode没有帮助。它在IDE中预览时返回运行时,如果通过编译的exe运行(可以说是纯运行时)。这是因为报表预览代码的结构。我们基本上大部分时间都会获取报告的副本,并在预览中将其加载到查看器中,而不考虑许可证上下文。这就是它给运行时的原因。

我还尝试使用processname进行检查,当运行IDE时,它提供了vs exe的名称:devenv可以使用但有些不可靠,因为它可以手动更改以命名其他内容。

运行throgh IDE时,

getEntryAssembly确实返回NULL,我认为这是最可靠的。我还没有找到任何其他方法,但我认为必须有其他方法来看待这种区别。

这是我在报告的格式事件中使用的codesnippet

//((这作为IComponent).Site == null)
            //对于通过设计器预览的纯运行时pr,这种情况都是正确的。

        // use licensemode usage.
        this.textBox1.Text += "LicenseUsageMode:   " + LicenseManager.UsageMode;

        this.textBox1.Text += "\r\n";

        // getEntryassembly
        if (System.Reflection.Assembly.GetEntryAssembly() == null)
            this.textBox1.Text += "GetEntryAssembly:   null";
        else
            this.textBox1.Text += "GetEntryAssembly:   NOT null";

        this.textBox1.Text += "\r\n";
        // System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe")
        this.textBox1.Text += "Process.GetCurrentProcess().ProcessName:   ";
        this.textBox1.Text += System.Diagnostics.Process.GetCurrentProcess().ProcessName ;
        this.textBox1.Text += "\r\n";
这给了我:

在IDE中预览时的LicenseManger值:LicenseManager.UsageMode是RunTime 在纯运行时预览时的LicenseManger值(例如按钮单击):LicenseManager.UsageMode是RunTime

在IDE中预览时

getEntryassembly值:null 在纯运行时预览时的getEntryassembly值(例如按钮单击):NOT null

在IDE中预览时的

processname值:devenv.exe(如上所述,有点不可靠) 在纯运行时预览时的processname值(例如按钮单击):NOT devenv.exe