简体   繁体   English

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

[英]Validation Error template doesn't show the Error result WPF

I am new in WPF I want validate my IP address but I have a problem: when I try to show the error message, it shows me only an empty red border.我是 WPF 新手我想验证我的 IP 地址,但我有一个问题:当我尝试显示错误消息时,它只显示一个空的红色边框。

Here is the ControlTemplate and all the code:这是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 file : 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 file : 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);
    }
}

I've found the solution (after a sleep:).我找到了解决方案(睡了一觉后:)。 In fact the exact element source you have to bind to can be accessed via the AdornedElementPlaceholder .实际上,您必须绑定到的确切元素源可以通过AdornedElementPlaceholder访问。 It has a property called AdornedElement , TemplateBinding does not work in this case because TemplatedParent does not point to the TextBox , it's just another Control which is used for ErrorTemplate control.它有一个叫做财产AdornedElementTemplateBinding不起作用在这种情况下,因为TemplatedParent不指向TextBox ,它只是一个控制它用于ErrorTemplate控制。 So the code should be like this:所以代码应该是这样的:

<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"/>

Note about how we set the attached property Validation.Errors for the AdornedElement .请注意我们如何为AdornedElement设置附加属性Validation.Errors Also note about the name adorner which is exactly the name you set for the AdornedElementPlaceholder .还要注意名称adorner ,它正是您为AdornedElementPlaceholder设置的名称。 I've made a demo and surely it should work.我做了一个演示,它肯定可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM