2010-07-20 2 views
3

Я (верю) Я подключаю проверку DataBinding в учебнике, но он просто не работает - вообще.WPF DataBinding Валидация игнорируется

В отладчике метод Validate(object value, CultureInfo cultureInfo) никогда не вызывается.

Что дает? Кроме того, для бонусных очков любые указатели на отладку WPF были бы потрясающими.

Я отправляю мой XAML и класс в вопросе

<UserControl x:Class="FooControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:Foo.Controls" 
     mc:Ignorable="d" 
     d:DesignWidth="300"> 
<Grid Name="GridFoo"> 
    <Grid.Resources> 
     <local:ValueConverter x:Key="MyConverter" /> 
    </Grid.Resources> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 
    <TextBox Name="TextBoxScalar" Grid.Column="0" TextAlignment="Right"> 
     <TextBox.Text> 
      <Binding Mode="OneWay" Path="Scalar" NotifyOnValidationError="True" ValidatesOnDataErrors="True" ValidatesOnExceptions="True"> 
       <Binding.ValidationRules> 
        <local:ScalarValidationRule /> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 
    <TextBlock Name="TextBlockUnit" Grid.Column="1" TextAlignment="Left" Padding="3"> 
     <Hyperlink> 
      <!-- Use a custom converter here b/c generics break wpf... --> 
      <Run Text="{Binding Mode=OneWay, Path=Unit, Converter={StaticResource MyConverter}}" /> 
     </Hyperlink> 
    </TextBlock> 
</Grid> 

ValidationRule

public class ScalarValidationRule : ValidationRule 
{ 
    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     string number = value as string; 
     double d; 
     return new ValidationResult(Double.TryParse(number, NumberStyles.Any, cultureInfo, out d), 
      String.Format("\"{0}\" is not a number.", number)); 
    } 
} 

ответ

7

Вы добавляете ValidationRule в одну сторону связывания. Односторонние привязки никогда не подталкивают значение к источнику, поэтому нечего проверять, и ваш ValidationRule никогда не вызывается. Если вы хотите проверить данные, введенные пользователем, установите Mode="TwoWay" на вашу привязку. Вы также можете полностью опустить атрибут Mode, так как TextBox.Text связывается по умолчанию в двух направлениях.

Если вам действительно нужна привязка в одностороннем порядке, и вы хотите, чтобы проверка выполнялась, когда значение передается от источника (Scalar) к цели (TextBox.Text), затем установите ValidatesOnTargetUpdated в значение True в ValidationRule. Вы можете сделать это в XAML или в конструкторе класса ValidationRule.

+0

Вопрос и ответ. Благодарю. – pomeroy

+1

Хороший ответ хорош даже после большого периода времени :) – Koscik

0

Вам не нужно указывать режим привязки. и установите ValidatesOnTargetUpdated на false/true, исходя из вашего требования, поскольку оба работают.