这适用于将ESRI MapControl嵌入Access数据库表单。
我有两个访问文件,分为前端和后端。我的后端也是一个PersonalGeoDatabase,ArcGIS用它来存储要在From嵌入式ESRI地图控件上显示的要素类。
要素类存储与特定ProjectID关联的折线,点和多边形。
从前端开始,我有嵌入式mapControl,它会加载绑定到后端的MXD文件。
我有一个名为CenterPoint的VB函数,巧合的是,它将地图包络围绕Project的相关要素类(如果存在)居中,并设置所需的查看范围。如果项目的要素类尚不存在,则会将地图集中在包含所有项目的整个区域中,并给出概述。
所以,如果这一切都有意义,我没有失去你......
我最初在Form_Current事件中调用了CenterPoint子。这是有效的,因为它执行了所需的所有功能;但是,当CenterPoint函数运行时,表单没有响应,阻止更改到另一个记录,直到重新绘制完成。这意味着,如果你希望跳过10个记录,你必须跳1,等待重新绘制,跳转另一个,等待重新绘制等。我通过优化MXD图像来大幅加速重绘层,但它仍然是不可接受的。
接下来,我尝试建立一个几秒的延迟,然后通过运行以下命令调用CenterPoint sub:
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)。 / p>
更奇怪的是,它偶尔会给我一个除以零误差的除法:
Do While Timer < s_Start + s_Delay
尽管没有划分界限。
所以,我想我的问题是:
现在,我的工作是将CenterPoint子项作为表单上按钮的单击事件,这可以工作,但并不理想。
如果其中任何一项没有意义,或者需要更多信息,请告诉我。
谢谢, 斯潘塞
答案 0 :(得分: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
答案 1 :(得分:0)
另一种可能性是将调用保持在OnCurrent事件中,但使用OnCurrent外部的时间标志来确定是否调用子例程。
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
现在,这是空中代码,所以我可能有一两个错误,但想法是只在延迟过期后运行代码。一旦它过期,你将开始时间设置回0,这样计数器将重新开始。
结果是对CenterPoint的调用只会发生在延迟过期后发生的OnCurrent事件上。