验证错误模板不显示错误结果WPF

时间:2014-07-14 16:46:46

标签: c# wpf validation

我是WPF的新手我想验证我的IP地址但是我有一个问题:当我尝试显示错误消息时,它只显示一个空的红色边框。

以下是ControlTemplate和所有代码:

<Window x:Class="SOTCBindingValidation.Window1"
        x:Name="This"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SOTCBindingValidation"
        Title="SOTC Validation Test" Height="150" Width="400">
  <Window.Resources>
    <local:ErrorsToMessageConverter x:Key="eToMConverter"/>

    <ControlTemplate x:Key="customvalidatortemplate">
      <StackPanel Orientation="Horizontal">
        <Border BorderThickness="1" BorderBrush="Red" VerticalAlignment="Top">
          <Grid>
            <AdornedElementPlaceholder x:Name="adorner" Margin="-1"/>
          </Grid>
        </Border>
        <Border x:Name="errorBorder" Background="Red" Margin="8,0,0,0"
                CornerRadius="0" IsHitTestVisible="False">
          <TextBlock Text="{Binding ElementName=AddressBox, 
                     Path=(Validation.Errors),
                     Converter={StaticResource eToMConverter}}" 
                     Foreground="White" FontFamily="Segoe UI"
                     Margin="8,2,8,3" TextWrapping="Wrap"
                     VerticalAlignment="Center"/>
        </Border>
      </StackPanel>
    </ControlTemplate>         
  </Window.Resources>

  <StackPanel Margin="5">
    <TextBlock Margin="2">Enter An IPv4 Address:</TextBlock>
    <TextBox x:Name="AddressBox"
             Validation.ErrorTemplate="{StaticResource customvalidatortemplate}"
             Margin="0,0,235.5,0">
      <TextBox.Text>
        <Binding ElementName="This" Path="IPAddress" 
                 UpdateSourceTrigger="PropertyChanged">
          <Binding.ValidationRules>
            <local:IPv4ValidationRule/>
          </Binding.ValidationRules>
        </Binding>
      </TextBox.Text>
    </TextBox>    
  </StackPanel>
</Window>

ErrorsToMessageConverter.cs文件:

public class ErrorsToMessageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var sb = new StringBuilder();
        var errors = value as ReadOnlyCollection<ValidationError>;
        if (errors != null)
        {
            foreach (var e in errors.Where(e => e.ErrorContent != null))
            {
                sb.AppendLine(e.ErrorContent.ToString());
            }
        }

        return sb.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

IPv4ValidationRule.cs文件:

public class IPv4ValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var str = value as string;
        if (String.IsNullOrEmpty(str))
        {
            return new ValidationResult(false,
                "Please enter an IP Address.");
        }

        var parts = str.Split('.');
        if (parts.Length != 4)
        {
            return new ValidationResult(false,
                "IP Address should be four octets, seperated by decimals.");
        }
        foreach (var p in parts)
        {
            int intPart;
            if (!int.TryParse(p, NumberStyles.Integer, cultureInfo.NumberFormat, out intPart))
            {
                return new ValidationResult(false,
                    "Each octet of an IP Address should be a number.");
            }

            if (intPart < 0 || intPart > 255)
            {
                return new ValidationResult(false,
                    "Each octet of an IP Address should be between 0 and 255.");
            }
        }

        return new ValidationResult(true, null);
    }
}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案(睡了之后:)。事实上,您必须绑定的确切元素源可以通过AdornedElementPlaceholder访问。它有一个名为AdornedElement的属性,TemplateBinding在这种情况下不起作用,因为TemplatedParent没有指向TextBox,它只是另一个使用的控件用于ErrorTemplate控制。所以代码应该是这样的:

<TextBlock Text="{Binding ElementName=adorner, 
                          Path=AdornedElement.(Validation.Errors),
                          Converter={StaticResource eToMConverter}}" 
           Foreground="White" FontFamily="Segoe UI" Margin="8,2,8,3" 
           TextWrapping="Wrap" VerticalAlignment="Center"/>

请注意我们如何为Validation.Errrors设置附加属性AdornedElement。另请注意名称adorner,它正是您为AdornedElementPlaceholder设置的名称。我做了一个演示,肯定它应该可以工作。