Используйте функцию callback()
внутри успеха foo()
. Попробуйте таким образом. Это просто и легко понять. & nbsp;
var lat = "";
var lon = "";
function callback(data) {
lat = data.lat;
lon = data.lon;
}
function getLoc() {
var url = "http://ip-api.com/json"
$.getJSON(url, function(data) {
callback(data);
});
}
getLoc();
«Я также могу поместить логическое поле, которое не установлено в true, пока форма не будет полностью загружена и не обработает события, если это ложь, но это грязный хак».
Это также облегчение и лучший способ сделать это!
Допустим, .NET предоставляет опрятный способ превратить и выключить все обработчики событий до тех пор, пока форма не будет загружена. Даже те, с кем вы работаете. Было бы недостаточно гибко отключить то, что вы хотели включить, но отключить то, что вы не сделали. Часто происходят установки формы, и вы хотите, чтобы события срабатывали. Кроме того, форма не будет строиться правильно, если огонь no срабатывает.
Чтобы заставить его чувствовать себя немного менее грязным, если вы инициализируете элементы управления в конструкторе формы, вы можете использовать свойство IsHandleCreated , а не собственный bool, чтобы проверить, должно ли оно на самом деле подтвердить или нет. Я бы подумал, что обычно вы не хотите проверять что-либо до того, как оно будет показано в первый раз, и дескриптор не будет создан до тех пор, пока он не будет.
Пример кода:
Private Sub myRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles myRadioButton.CheckedChanged
If myRadioButton.Checked AndAlso myRadioButton.IsHandleCreated Then
'Do Work
End If
End Sub
Для radiobutton
см. Ответ Ханса Олссона
Для числового вниз, сделайте это так
Private Sub myNumeric_ValueChanged(sender As Object, e As EventArgs) Handles myNumeric.ValueChanged
If myNumeric.Value >= 0 AndAlso myNumeric.IsHandleCreated Then
'Do the work
End If
End Sub
Ключевое слово: myNumeric.Value
и IsHandleCreated
Я помещаю публичную переменную в файл Module1 Dim Public bolForm_LoadingTF как Boolean = True
В каждом событии formLoad я помещаю bolForm_LoadingTF = True
В каждом элементе управления с событием OnSelectedIndexChanged I put if bolForm_LoadingTF = True then Exit Sub
В конце формы load event я помещаю bolForm_LoadingTF = False
Я, вероятно, нарушаю кучу правил, но это работает для меня.
Возможно, для некоторых функций вы можете использовать событие click вместо события с измененной проверкой.
На всякий случай, если кто-то все еще ищет это, событие запускается при инициализации формы. НО форма еще не видна. Также скажите, что у вас есть отношение внешнего ключа, по которому у вас есть значение по умолчанию, необходимое для каждой проблемы обновление строки тоже. Поэтому для меня работал следующий код ....
if (Visible && !(e.ColumnIndex == 0))
{
phoneEdited = true;
MessageBox.Show("A Phone entry has been entered");
}
Еще один способ:
Private Sub dgvGroups_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvGroups.CellValueChanged
If Me.Visible = False Then Exit Sub ' Sub gets called on form load which causes problems
wksGroups.Cells(e.RowIndex + 1, 1) = dgvGroups.Item(e.ColumnIndex, e.RowIndex).Value
wksGroups.Cells(1, 5) = dgvGroups.RowCount
Легкое решение состоит в том, чтобы объявить инициализирующую переменную:
Private Initializing as boolean = True
Private Sub rb_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbNuevos.CheckedChanged, RbDesaparecidos.CheckedChanged, RbModificados.CheckedChanged, RbNoDesap.CheckedChanged, RbDesHoy.CheckedChanged, RbChT.CheckedChanged
if Initializing then return
'Your Code
End Sub
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
initializing = false
end sub
Самое сложное: удалить «дескрипторы» из метода и использовать AddHandler
для нового метода.
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
AddHandler RbChT.CheckedChanged, AddressOf rb_CheckedChanged
end sub
(Использование VS 2017) Мне кажется, что это раздражение, но не ошибка. Это согласуется с используемой моделью. Событие запускается при нормальной работе кода, но код, который я не писал (но может получить доступ к тому, где дураки опасаются протектора), и там, где, как представляется, нет (приличного) места раньше обычного потока, чтобы его предвидеть.
Самый чистый ответ, по-видимому, заключается не в том, чтобы вообще не проверять элементы управления флажком или флажком в дизайнере, если они инициируют какой-либо значительный код. Вместо этого эти элементы управления должны быть изменены кодом (например, checked = true) в событии Load (например) ПОСЛЕ завершения всей инициализации.
Здесь нет никакой гибкости, поскольку оба фиксируются перед сборкой только в разных местах. Обработчики событий будут обрабатывать его точно так же, как если бы пользователь нажал элемент управления в естественном потоке хорошо разработанного графического интерфейса. (Это напоминает мне древнюю RPG-пословицу «Не зацикливайся на цикле». (Кто-нибудь здесь помнит RPG? Я, а не часть команды, ориентированной на IBM, никогда не использовал ее, но имел интересные обсуждения с некоторыми, кто это сделал.) Предварительная проверка
Если по какой-либо причине это не сработает, следующая лучшая вещь - это kludge, предложенный в другом месте одного логического инициализированного логического значения, и установите значение true в соответствующее время с условными выходами в необходимых местах, чтобы предотвратить их сбой до тех пор. Он выполнит свою работу, но это уродливо. Лучше, чем неудача.
Еще одна вещь, которую я пробовал, прежде чем я решил, что проблема с предустановленными проверками на уровне дизайнера была проблемой, и была очень приемлемая альтернатива - это поставить опасные пятна в Try..Catch игнорировать исключение. Также kludge.
Одна вещь, которую я обнаружил, что работы добавляет события вручную после загрузки формы.
Для этого вы можете просто перейти в сгенерированный код формы, найденный в файле конструктора этой формы, и вытащить строки, которые добавляют событие. Он будет выглядеть примерно так:
this.controlName.CheckedChanged += new System.EventHandler(this.controlName_CheckedChanged);
Затем все эти вызовы помещаются в метод, который вы вызываете после вызова InitializeComponent в конструкторе формы.