Как обработать исключение в конвертере значений, чтобы отображалось пользовательское сообщение об ошибке - PullRequest
14 голосов
/ 25 мая 2011

У меня есть текстовое поле, которое привязано к классу со свойством типа 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");
        }
    }

Я установил 'ValidatesOnExceptions= True 'в привязке XAML.

Однако я натолкнулся на следующую статью MSDN, в которой объясняется, почему вышеуказанное не будет работать:

"Механизм привязки данных не перехватывает исключения, которыевыдается преобразователем, предоставленным пользователем. Любое исключение, которое выдается методом Convert, или любые неперехваченные исключения, которые вызываются методами, вызываемыми методом Convert, обрабатываются как ошибки времени выполнения "

У меня естьпрочитайте, что 'ValidatesOnExceptions действительно перехватывает исключения в TypeConverters, поэтому мои конкретные вопросы:

  • Когда вы будете использовать TypeConverter поверх ValueConverter
  • Предполагая, что TypeConverter не является решением вышеупомянутой проблемы, как я могу отобразить свое пользовательское сообщение об ошибке в пользовательском интерфейсе

Ответы [ 3 ]

10 голосов
/ 25 мая 2011

Я бы использовал для этого 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>

screenshot

7 голосов
/ 17 сентября 2012

Я использовал проверку и конвертер, чтобы принять 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;
    }
}
0 голосов
/ 25 мая 2011

Вы не должны выбрасывать исключения из конвертера.Я хотел бы реализовать IDataErrorInfo и реализовать ошибки и строки на этом.Пожалуйста, проверьте http://www.codegod.biz/WebAppCodeGod/WPF-IDataErrorInfo-and-Databinding-AID416.aspx. HTH Даниэль

...