2

这涉及将 ESRI MapControls 嵌入到 Access 数据库表单中。

我有两个访问文件,分为前端和后端。我的后端也是一个 PersonalGeoDatabase,ArcGIS 使用它来存储一个要素类,以便在来自嵌入式 ESRI 地图控件上显示。

要素类存储与特定 ProjectID 关联的折线、点和多边形。

从前端,我有嵌入的 mapControl,它加载绑定到后端的 MXD 文件。

我有一个名为 CenterPoint 的 VB 函数,巧合的是,它将地图包络围绕项目的关联要素类(如果存在)居中,并设置所需的查看范围。如果项目的要素类尚不存在,它会将地图以包含所有项目的整个区域为中心,提供总体概览。

所以,如果这一切都说得通,而且我没有失去你……

我最初在 Form_Current 事件中调用了 CenterPoint 子。这很有效,因为它执行了所需的所有功能;但是,当 CenterPoint 函数运行时,表单没有响应,在重新绘制完成之前无法更改到另一个记录。这意味着,如果您希望跳过 10 条记录,则必须跳过 1 条,等待重新绘制,跳转另一个,等待重新绘制,等等。我通过优化 MXD 图像和层,但它仍然是不可接受的。

接下来,我尝试建立几秒钟的延迟,然后通过运行以下命令调用 CenterPoint 子:

Private Sub Form_Current()
    Dim s_Start As single
    Dim s_Delay As single
    s_Start = Timer
    Do While Timer < s_Start + s_Delay
        DoEvents
    Loop

CenterPoint

End Sub

这通过使用 DoEvents 调用为我提供了所需的响应能力,这意味着我可以在它第一次尝试重新绘制之前单击多个记录。

不幸的是,它显然缓存了所有 Form_Current 调用,如果我跳过 3 条记录,等待延迟结束,然后观看屏幕,它将连续 3 次重新绘制(即运行 CenterPoint)。

更奇怪的是,它是否偶尔给我一个除以零错误的行:

Do While Timer < s_Start + s_Delay

尽管没有分工。

所以,我想我的问题是:

  1. 有没有办法只运行一次 form_current 调用?
    • 如果没有,在我调用 CenterPoint 函数之前,有没有办法确保用户在给定时间内停留在当前记录上?
  2. 有没有办法将我的小于比较与除以零错误隔离,所以至少,即使它会重新绘制多次,用户也可以快速连续点击记录?

现在,我的工作是将 CenterPoint 子作为表单上按钮的单击事件,这可行,但并不理想。

如果其中任何一个没有意义,或者需要更多信息,请告诉我。

谢谢,斯宾塞

4

2 回答 2

1

回答您的问题:
1) Form_ Current 将始终在您切换记录时运行。没有选择。因此,下一个最佳选择是将对 CenterPoint 的调用移至另一个事件。我会使用表单计时器事件,并在每次通过 Form_Current 时重置计时器,当计时器用完时,它会关闭 CenterPoint。

Private Sub Form_Current()
    Me.TimerInterval = 10000
End Sub

Private Sub Form_Timer()
    CenterPoint
End Sub

2)如果您使用的是表单计时器事件,您可能不再需要此代码;然而,

Private Sub Form_Current()
Dim l_Start As long 
Dim l_Delay As long 
Dim l_endTime As long 'or integers - time is returning the number of seconds 
                      'since midnight, not a real... this may be the source 
                      'of your problem

    l_Delay = 1000 ' I didn't see you set s_Delay any where
    l_Start = Timer
    l_endTime = l_Start + l_Delay 'lets do the calculation only once.

'This might break down if the user switch records just before midnight
'(never ending loop)
'    Do While Timer < l_endTime 
'        DoEvents
'    Loop

    'Instead I would do this
    Do While (Timer <= l_endTime) _
                and (l_start <= timer)
        DoEvents
    Loop

    CenterPoint

End Sub
于 2009-02-06T15:41:48.507 回答
0

Another possibility would be to keep the call in the OnCurrent event, but use a time flag outside the OnCurrent to determine whether or not to call the subroutine.

  Static s_Start As Single
  Dim s_Delay As Single

  If s_Start = 0 Then
     s_Start = Timer
  End If
  If Timer > s_Start + s_Delay
     Call CenterPoint
     s_Start = 0
  End If

Now, that's air code, so I may have a mistake or two in it, but the idea is that you run the code only once the delay has expired. And once it's expired, you set the start time back to 0 so that counter will start over again.

The result is that the call to CenterPoint will happen only on those OnCurrent events that happen after your delay has expired.

于 2009-02-06T22:55:47.350 回答