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

时间:2011-05-25 11:39:32

标签: wpf data-binding 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");
        }
    }

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

但是,我遇到了以下MSDN文章,该文章解释了上述原因无效的原因:

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

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

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

3 个答案:

答案 0 :(得分:10)

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

e.g。 (注意工具提示绑定

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

screenshot

答案 1 :(得分: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>

代码背后:

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

ValidationRule:

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

答案 2 :(得分:0)

您不应该从转换器中抛出异常。我将实现IDataErrorInfo并在其上实现错误和字符串。请检查http://www.codegod.biz/WebAppCodeGod/WPF-IDataErrorInfo-and-Databinding-AID416.aspx。 HTH daniell