如何在Value转换器中处理异常,以便可以显示自定义错误消息

stu*_*ree 16 data-binding wpf ivalueconverter

我有一个文本框绑定到具有类型Timespan属性的类,并编写了一个值转换器将字符串转换为TimeSpan.

如果在文本框中输入非数字,我希望显示自定义错误消息(而不是默认的"输入字符串格式错误").

转换器代码是:

    public object ConvertBack(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        try
        {
            int minutes = System.Convert.ToInt32(value);
            return new TimeSpan(0, minutes, 0);
        }
        catch
        {
            throw new FormatException("Please enter a number");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在XAML绑定中设置了'ValidatesOnExceptions = True'.

但是,我遇到了以下MSDN文章,它解释了为什么以上内容不起作用:

"数据绑定引擎不会捕获由用户提供的转换器抛出的异常.Rinit方法抛出的任何异常,或者Convert方法调用的方法抛出的任何未捕获的异常都被视为运行时错误"

我已经读过'ValidatesOnExceptions确实捕获TypeConverters中的异常,所以我的具体问题是:

  • 您何时可以在ValueConverter上使用TypeConverter
  • 假设TypeConverter不是上述问题的答案,我如何在UI中显示我的自定义错误消息

H.B*_*.B. 10

我会使用a ValidationRule,这样转换器可以确保转换有效,因为只有在验证成功时才调用它,并且你可以使用附加属性Validation.Errors,ValidationRule如果输入不是你的方式,它将包含你创建的错误想要它.

例如(注意工具提示绑定)

<TextBox>
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="Background" Value="Pink"/>
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
    <TextBox.Text>
        <Binding Path="Uri">
            <Binding.ValidationRules>
                <vr:UriValidationRule />
            </Binding.ValidationRules>
            <Binding.Converter>
                <vc:UriToStringConverter />
            </Binding.Converter>
        </Binding>
    </TextBox.Text>
</TextBox>
Run Code Online (Sandbox Code Playgroud)

截图


Muh*_*laa 7

我使用验证和转换器来接受null和编号

XAML:

<TextBox x:Name="HeightTextBox" Validation.Error="Validation_Error">
    <TextBox.Text>
        <Binding Path="Height"
                 UpdateSourceTrigger="PropertyChanged" 
                 ValidatesOnDataErrors="True"
                 NotifyOnValidationError="True"
                 Converter="{StaticResource NullableValueConverter}">
            <Binding.ValidationRules>
                <v:NumericFieldValidation />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
Run Code Online (Sandbox Code Playgroud)

代码背后:

private void Validation_Error(object sender, ValidationErrorEventArgs e)
{
    if (e.Action == ValidationErrorEventAction.Added)
        _noOfErrorsOnScreen++;
    else
        _noOfErrorsOnScreen--;
}

private void Confirm_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = _noOfErrorsOnScreen == 0;
    e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)

验证规则:

public class NumericFieldValidation : ValidationRule
{
    private const string InvalidInput = "Please enter valid number!";

    // Implementing the abstract method in the Validation Rule class
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        float val;
        if (!string.IsNullOrEmpty((string)value))
        {
            // Validates weather Non numeric values are entered as the Age
            if (!float.TryParse(value.ToString(), out val))
            {
                return new ValidationResult(false, InvalidInput);
            }
        }

        return new ValidationResult(true, null);
    }
}
Run Code Online (Sandbox Code Playgroud)

转换器:

public class NullableValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (string.IsNullOrEmpty(value.ToString()))
            return null;
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)