【问题标题】:Custom component doesn't return value when the validation is not successful验证不成功时自定义组件不返回值
【发布时间】:2020-10-25 09:51:15
【问题描述】:

我正在 Blazor 中创建一个简单的自定义货币组件。我继承自InputBase<string> 并实现bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)

问题是我想在TryParseValueFromString 不成功时返回值。

父组件

 <div class="form-group mb-3">
            <label for="MyInputTextArea">Input currency</label>
            <InputCurrency @bind-Value=FormData.SomeStringCurrency id="MyInputTextArea" class="form-control"/>
            <ValidationMessage For="() => FormData.SomeStringCurrency"></ValidationMessage>
        </div>

自定义组件

@using System.Globalization
@inherits InputBase<string>

<input type="string" @attributes=AdditionalAttributes class=@CssClass @bind=CurrentValueAsString />

@code{
private CultureInfo _culture = CultureInfo.CreateSpecificCulture("de");

protected override string FormatValueAsString(string value)
{
    if (string.IsNullOrWhiteSpace(value))
    {
        return string.Empty;
    }

    if (Decimal.TryParse(value, NumberStyles.Currency, _culture, out decimal result))
    {
        return Convert.ToDecimal(value).ToString("N", _culture);
    }
    else
    {
        return value;
    }
}

protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
{
    try
    {
        var decimalValue = ReturnDecimalIfSuccessFul(value);

        result = decimalValue.ToString();
        validationErrorMessage = null;
        return true;
    }
    catch
    {
        validationErrorMessage = "Not a valid currency value.";
        result = value; // here i am assigning the value but it's not returned 
        return false;
    }
}

private decimal? ReturnDecimalIfSuccessFul(string value)
{
    if (string.IsNullOrWhiteSpace(value))
    {
        return null;
    }

    var result = Decimal.Parse(value, NumberStyles.Currency, _culture);
    
    return result;
}

user input

result

what i expect

当值未成功解析时,不会向用户显示。仅显示最后一个成功的值,但我希望始终让用户输入的值...

【问题讨论】:

    标签: blazor


    【解决方案1】:

    复制运行并测试...

    InputCurrency.razor

    @using System.Globalization
    @inherits InputBase<string>
    
    <input type="text" @attributes="AdditionalAttributes" class=@CssClass value="@CurrentValue" 
                                                             @onchange="OnInputValueChanged" />
    
    @code{
        private CultureInfo _culture = CultureInfo.CreateSpecificCulture("de");
    
        protected async Task OnInputValueChanged(ChangeEventArgs e)
        {
            CurrentValueAsString = e.Value.ToString();
            await Task.CompletedTask;
        }
    
        protected override string FormatValueAsString(string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                return string.Empty;
            }
    
            if (Decimal.TryParse(value, NumberStyles.Currency, _culture, out decimal result))
            {
                return Convert.ToDecimal(value).ToString("N", _culture);
            }
            else
            {
                return value;
            }
        }
    
        protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
        {
            try
            {
                var decimalValue = ReturnDecimalIfSuccessFul(value);
    
                result = decimalValue.ToString();
                validationErrorMessage = null;
                return true;
            }
            catch
            {
                validationErrorMessage = "Not a valid currency value.";
                result = value; // here i am assigning the value but it's not returned
                return false;
            }
        }
    
        private decimal? ReturnDecimalIfSuccessFul(string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                return null;
            }
    
            var result = Decimal.Parse(value, NumberStyles.Currency, _culture);
    
            return result;
        }
    }
    

    Index.razor

    @page "/"
    
    <EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
        <DataAnnotationsValidator />
    
        <div class="form-group">
            <label for="name">Name: </label>
            <InputText Id="name" Class="form-control" @bind-Value="@product.Name"></InputText>
            <ValidationMessage For="@(() => product.Name)" />
    
        </div>
    
        <div class="form-group">
            <label for="MyInputTextArea">Input currency</label>
            <InputCurrency @bind-Value=product.Price id="MyInputTextArea" class="form-control" />
            <ValidationMessage For="() => product.Price"></ValidationMessage>
        </div>
        <p>
            <button type="submit">Save</button>
        </p>
    </EditForm>
    
    @code
        {
    
        private EditContext EditContext;
        private Product product = new Product();
       
    
        protected override void OnInitialized()
        {
            EditContext = new EditContext(product);
    
            base.OnInitialized();
        }
    
    
        public async Task HandleValidSubmit()
        {
       
            await Task.Run(() =>
            {
                Console.WriteLine("Saving...");
               
            });
    
        }
    
        public class Product
        {
            public string Name { get; set; }
            public string Price { get; set; }
        }
    }
    

    【讨论】:

    • 是的,基本上它解决了我的答案。我不知道没有必要调用FormatValueAsString,谢谢!
    猜你喜欢
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多