Перехват неявной ошибки преобразования WPF - PullRequest
2 голосов
/ 08 марта 2011

У меня есть WPF TextBox, который связан с целочисленным свойством.Если я введу какие-либо буквы в текстовое поле, текстовое поле отображает красную рамку, когда оно теряет фокус, указывая на ошибку преобразования.Пока все хорошо.

Я хочу отловить ошибку преобразования в коде.Я думал, что ошибка произошла из-за исключения преобразования, и что ExceptionValidationRule для объекта привязки текстового поля не пройдет проверку в этих случаях.Однако, похоже, что это не так.

В следующем примере я бы попросил фон стать оранжевым, когда введена текстовая строка, и я нажимаю кнопку, но этого не происходит.

XAML:

<Window x:Class="ValidationTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ValidationTest="clr-namespace:ValidationTest" 
    Title="MainWindow" Height="89" Width="239">
<Grid>
    <TextBox Height="27" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" >
        <TextBox.Text>
            <Binding Path="IntegerField">
                <Binding.ValidationRules>
                    <ExceptionValidationRule />
                    <!--ValidationTest:IntegerValidationRule /-->
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <Button Content="Test" Height="27" HorizontalAlignment="Left" Margin="146,12,0,0" Name="button1" VerticalAlignment="Top" Width="60" Click="button1_Click" />
</Grid>

Код позади:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Globalization;

namespace ValidationTest {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public int IntegerField { get; set; }

        public MainWindow() {
            InitializeComponent();
            this.DataContext = this;
        }

        private void button1_Click(object sender, System.Windows.RoutedEventArgs e) {
            // Validate all the bindings on the textbox 
            bool valid = true;
            LocalValueEnumerator localValues = textBox1.GetLocalValueEnumerator();
            while (localValues.MoveNext()) {
                LocalValueEntry entry = localValues.Current;
                if (BindingOperations.IsDataBound(textBox1, entry.Property)) {
                    Binding binding = BindingOperations.GetBinding(textBox1, entry.Property);
                    foreach (ValidationRule rule in binding.ValidationRules) {
                        ValidationResult result = rule.Validate(textBox1.GetValue(entry.Property), null);
                        if (!result.IsValid) {
                            valid = false;
                        }
                    }
                }
            }
            this.Background = valid ? Brushes.Green : Brushes.Orange;
        }

    }

    public class IntegerValidationRule : ValidationRule {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
            int val;
            if (!int.TryParse(value as string, out val)) {
                return new ValidationResult(false, "NAN");
            }
            return ValidationResult.ValidResult;
        }
    }
}

Я могу добиться желаемой функциональности в примере, раскомментировав пользовательский IntegerValidationRule в XAML... но это не применимо в моем "реальном" приложении, потому что типы данных, к которым привязаны текстовые поля, неизвестны во время разработки.

Кто-нибудь знает решение этой проблемы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...