Карты задержки ArcGIS MapControl и Ms Access перерисовываются?

Это относится к встраиванию ESRI MapControls в формы базы данных Access.

У меня есть два файла доступа, разделенные на интерфейс и серверную часть. Моя бэкэнд также является PersonalGeoDatabase, которую ArcGIS использует для хранения класса пространственных объектов для отображения во встроенном элементе управления картой ESRI.

Класс пространственных объектов хранит полилинии, точки и полигоны, связанные с конкретным ProjectID.

Из интерфейса у меня есть встроенный mapControl, который загружает файл MXD, привязанный к бэкэнду.

У меня есть функция VB под названием CenterPoint, которая по совпадению центрирует оболочку карты вокруг класса объектов, связанного с проектом (если он существует), и устанавливает желаемые пределы просмотра. Если класс пространственных объектов для проекта еще не существует, он центрирует карту вокруг всего региона, в котором находятся все проекты, давая общий обзор.

Итак, если все это имело смысл, и я не потерял тебя ...

Первоначально я вызывал подпрограмму CenterPoint в событии Form_Current. Это работало, поскольку выполняло все желаемые функции; однако, пока выполнялась функция 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 записи, дождусь окончания задержки и буду смотреть на экран, он будет повторно рисовать (т.е. запускать CenterPoint) 3 раза подряд.

Что еще более странно, это время от времени дает мне ошибку деления на ноль для строки:

Do While Timer < s_Start + s_Delay

несмотря на отсутствие разделения в линии.

Итак, я думаю, мои вопросы таковы:

  1. Is there a way to have access only run the form_current call once?
    • If not, is there a way to make sure a user has stayed on the current record for a given time before I call the CenterPoint function?
  2. Is there a way to insulate my less-than comparison from the division by zero error, so at least, even though it will re-draw multiple times, the user can click through records in rapid succession?

Прямо сейчас моя работа заключалась в том, чтобы поместить подпункт CenterPoint как событие щелчка для кнопки в форме, что работает, но не идеально.

Если что-то из этого не имеет смысла или требуется дополнительная информация, дайте мне знать.

Спасибо, Спенсер


person slawley    schedule 06.02.2009    source источник


Ответы (2)


Отвечая на ваши вопросы:
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
person BIBD    schedule 06.02.2009

Другая возможность - сохранить вызов в событии 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, которые происходят после того, как истечет ваша задержка.

person David-W-Fenton    schedule 06.02.2009
comment
@Joel Coehoorn Это немного грустно. Дэвид умер буквально в прошлом году. davis-andersonfuneralhome .com / obits / obituaries.php / obitID ​​/ - person Fionnuala; 25.05.2012