I am fairly new to WPF and I am slowly collecting tips and tricks from across the web to put my project together. I am currently having trouble getting all my ducks in a row for data validation using an AdornedElementPlaceholder.
in my resource file I have
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right"
Foreground="Orange"
FontSize="12pt"
ToolTip="{Binding ElementName=MyAdorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">***
</TextBlock>
<Border BorderBrush="Red" BorderThickness="2">
<AdornedElementPlaceholder Name="MyAdorner"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="MistyRose"/>
</Trigger>
</Style.Triggers>
</Style>
and this is the textbox I'm working with currently to make things work
<TextBox Grid.Column="2" Height="23" Name="txtRefreshTime" Width="60" MaxLength="3">
<TextBox.Text>
<Binding FallbackValue="59" RelativeSource="{RelativeSource Self}" Path="Text">
<Binding.ValidationRules>
<val:StringRangeValidationRule
MinimumLength="1"
ErrorMessage="Must have a numeric value."/>
<val:NumericInputValidationRule
IsAType="intType"
ErrorMessage="Must be a number of seconds."/>
<val:NumericRangeValidationRule
MinimumValue="5"
MaximumValue="900"
ErrorMessage="Value must be between 5 and 900 seconds (15 minutes)."/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Everything works exactly how I want it to EXCEPT once the validation takes place and an error is found I can't click and set focus on the textbox. I can tab to it but I can't click on it. I downloaded an example from here and the code doesn't show anything different and it works just fine. Any ideas on what I have wrong or a way to fix the problem?
I also have used this piece into the resource file as a replacement for the above. It is similar to the above bit of style and it also 'almost' works, but the tooltip doesn't show.
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<AdornedElementPlaceholder Name="controlWithError" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="MistyRose"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
And as requested some of the validation code
public class StringRangeValidationRule : ValidationRule
{
private int _minimumLength = -1;
private int _maximumLength = -1;
private string _errorMessage;
public int MinimumLength
{
get { return _minimumLength; }
set { _minimumLength = value; }
}
public int MaximumLength
{
get { return _maximumLength; }
set { _maximumLength = value; }
}
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
ValidationResult result = new ValidationResult(true, null);
string inputString = (value ?? string.Empty).ToString();
if (inputString.Length < this.MinimumLength ||
(this.MaximumLength > 0 &&
inputString.Length > this.MaximumLength))
{
result = new ValidationResult(false, this.ErrorMessage);
}
return result;
}
}