У меня есть 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... но это не применимо в моем "реальном" приложении, потому что типы данных, к которым привязаны текстовые поля, неизвестны во время разработки.
Кто-нибудь знает решение этой проблемы?