Основная проблема в том, что Blazor просто не собирается обновлять текстовое поле, если считает, что его значение не изменилось.Частично эта проблема в вашем примере заключается в том, что внутреннее представление значения (вашего свойства) иногда не соответствует тому, что вы видите в текстовом поле (2
против 2.00
).Но что касается Blazor, если значение свойства не меняется, оно не будет распространять привязку обратно в текстовое поле.
Я поиграл с несколькими вариантами вашего кода (ручная «привязка» с использованиемvalue
и onchange
) но, в конечном счете, если к тому времени, когда ваш код завершит обновление свойства value, и значение будет таким же, как было раньше, ничего не произойдет.
Единственный обходной путь, который я могу придуматьэто ввести действительно уродливый взлом с помощью асинхронного.Когда вы это сделаете, цикл обработки событий завершается после await
(Blazor примет новое значение 2
), и Blazor снова проверит, изменилось ли что-нибудь, когда он возобновит вызов await
с того моментаэто новый раунд цикла событий.Поскольку новое значение теперь будет 2.00
вместо 2
, оно обновит текстовое поле.
@functions {
private string value;
private string Value
{
get => value;
set => SetValue(value);
}
private async void SetValue(string value)
{
this.value = value;
await Task.Delay(1);
this.value = decimal.Parse(value).ToString("F2");
StateHasChanged();
}
}
Надеюсь, кто-то, кто знает больше о Блазоре, чем я, может предложить что-то менее зверское.Но это работает .(Кстати, Task.Delay(0)
не работает , а не , вероятно, из-за некоторой оптимизации, когда задача уже выполнена и поэтому не предполагает обещания выйти из цикла событий.)
Примечание:
Как только строки формата Blazor (то есть format-value="yyyy-MM-dd"
) принимают числа, вы, вероятно, сможете упростить это, просто сохранив значение в виде десятичной дроби и напрямую используя строку формата в разметке бритвы.