Мне все еще трудно привязаться к простому ярлыку. Проблема кажется простой, но я потратил дни зря, поэтому пришло время обратиться за помощью. Возможно, кто-то знает ответ.
В приведенном ниже коде кнопка работает каждый раз, но нажатие Enter не обновляет страницу, даже если переменная, привязанная к метке, изменилась (я проверил, выведя на консоль с помощью Serilog).
Короче говоря: кнопка и клавиша ввода правильно вызывают одну и ту же функцию, которая каждый раз выполняет задание. К сожалению, страница воспринимает изменение только с помощью кнопки, изменяя статус метки.
Теперь, если я дважды нажму Enter, то, похоже, это сработает, но это не покажет вам, что в фоновом режиме есть исключение, потому что это уже повторяющееся значение. Нажмите Enter в третий раз, и вы получите правильный статус.
Имейте в виду, что я новичок в C#, особенно в гибридных приложениях Maui Blazor.
Спасибо!
HTML:
<div> <button @onclick=PushToDatabaseFunction> upload to db </button> <input @onkeyup = "@(e => KeyPressHandler("inputFieldForUploading", e))" @bind-value:event = "oninput" @bind-value = "inputFieldString" type = "text" placeholder = "..." /> </div> <div> <label>Status Label: @statusLabelBindString</label> </div>
В моем коде:
private string statusLabelBindString = ""; private string inputFieldString = ""; private async void KeyPressHandler(string inputField, KeyboardEventArgs e) { if (e.Key == "Enter") { if (inputField == "inputFieldForUploading") await PushToDatabaseFunction(); } } private async Task PushToDatabaseFunction() { //code here takes the inputFieldString and adds it to a database //I've triple checked many many times and the code to the db works correctly await db.insertAsync(inputFieldString); //the following line also works correctly, as the statusLabelBindString variable > // takes on a new value. if (db.status= = "ok") statusLabelBindString = $" {inputFieldString} was added to db"; else statusLabelBindString = "Error - Duplicate value"; //Even though statusLabelBindString has a new value (I've checked), the label does not //update if you press Enter, but from the button it works fine. }
В чем может быть дело?
Спасибо!
Вы пытались сделать свой атрибут общедоступным?
Да, @ФахимАнис! Он просто не работает при вызове через KeyHandlerFunction. Я очень подозреваю, что это проблема времени, когда переменная не обновляется из-за сосредоточения внимания на элементе, но, блин, трудно найти истинную причину.
Прежде всего, я воспроизвел вашу проблему с await Task.Delay(1000);
:
private async Task PushToDatabaseFunction() {
await Task.Delay(1000);
statusLabelBindString = $" {inputFieldString} was added to db";
}
Приведенный выше код может воспроизвести вашу проблему. И я могу это исправить двумя способами:
StateHasChanged()
вручную, чтобы вы также могли попробовать:if (db.status= = "ok")
{
statusLabelBindString = $" {inputFieldString} was added to db";
StateHasChanged();
}
else{
statusLabelBindString = "Error - Duplicate value";
StateHasChanged();
}
await
в await Task.Delay(1000);
:private async Task PushToDatabaseFunction() {
Task.Delay(1000);
statusLabelBindString = $" {inputFieldString} was added to db";
}
Два способа позволяют боту обновить метку при первом нажатии Enter.
StateHasChanged()
, вы можете просто сделать KeyPressHandler
как async Task
вместо async void
.private async Task KeyPressHandler(string inputField, KeyboardEventArgs e)
{
if (e.Key == "Enter")
{
if (inputField == "inputFieldForUploading")
await PushToDatabaseFunction();
}
}
Когда вы используете async void
, пользовательский интерфейс никогда не обновляется (перерисовывается повторно), поскольку StateHasChanged()
никогда не вызывается средой выполнения, поскольку среда выполнения не знала, когда асинхронные методы вызвали возврат. Но Task
сообщит среде выполнения, когда метод вернется. Поэтому используйте async Task
вместо async void
.
Большое спасибо @Liyun Zhang - MSFT!!! Я забыл упомянуть одну вещь: метод db.Insert() является асинхронным, поэтому я не могу избавиться от ожидания. Пример кода должен был быть написан как «await db.insertAsync()». Я добавил StateHasChanged(), и он работает, но это все еще сводит меня с ума. Код тот же, но почему он не отображается при вызове из другой функции? Это все равно, что покрасить машину в красный цвет и написать поверх краски «Эта машина красная». Как-то лишнее.
Пожалуйста, проверьте третий метод в моем обновленном ответе. @BMET1
ты мужчина! Все предложенные вами решения сработали, но третье мне очень понравилось. Для меня это был полезный опыт. Большое спасибо, что нашли время.
Чтобы внести ясность: я пробовал много разных комбинаций. Я также понимаю, что существует функция StateHasChanged(), которая снова отображает экран, но у меня были неоднозначные результаты. Я чувствую, что мне не хватает чего-то довольно основного. Спасибо!