19

我有一个文本框,它绑定到具有 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");
        }
    }

我在 XAML 绑定中设置了“ValidatesOnExceptions=True”。

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

“数据绑定引擎不会捕获用户提供的转换器引发的异常。任何由 Convert 方法引发的异常,或由 Convert 方法调用的方法引发的任何未捕获的异常,都被视为运行时错误”

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

  • 你什么时候会在 ValueConverter 上使用 TypeConverter
  • 假设 TypeConverter 不是上述问题的答案,我如何在 UI 中显示我的自定义错误消息
4

3 回答 3

18

我会为此使用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>

截屏

于 2011-05-25T12:04:37.593 回答
9

我使用验证和转换器来接受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>

代码背后:

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;
}

验证规则:

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);
    }
}

转换器:

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;
    }
}
于 2012-09-17T14:24:39.763 回答
1

您不应该从转换器抛出异常。我将实现 IDataErrorInfo 并在其上实现 Error 和 String。请检查http://www.codegod.biz/WebAppCodeGod/WPF-IDataErrorInfo-and-Databinding-AID416.aspx。HTH丹尼尔

于 2011-05-25T12:18:56.553 回答