WPF中ValidationRule验证成功时如何显示提示消息?
Absolutely! You can definitely display a success message when ValidationResult returns true in WPF—while the built-in ErrorTemplate handles validation failures, we just need a few extra steps to show positive feedback. Here are three practical methods to implement this:
1. Use Style Triggers with Validation.HasError
The simplest approach is to leverage the Validation.HasError attached property, which is false when validation passes. You can override your control's template to include a hidden success message, then use a trigger to show it when validation succeeds.
<TextBox x:Name="ValidatingTextBox"> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <Grid> <!-- Default TextBox layout --> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer x:Name="PART_ContentHost"/> </Border> <!-- Success message (hidden by default) --> <TextBlock x:Name="SuccessHint" Text="✓ Input is valid!" Foreground="ForestGreen" Margin="0,22,0,0" Visibility="Collapsed"/> </Grid> <ControlTemplate.Triggers> <!-- Show success message when validation passes --> <Trigger Property="Validation.HasError" Value="False"> <Setter TargetName="SuccessHint" Property="Visibility" Value="Visible"/> </Trigger> <!-- Keep your existing error tooltip logic --> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </TextBox.Style> <!-- Your existing ValidationRule setup --> <TextBox.Text> <Binding Path="UserInput" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:MyInputValidationRule ValidatesOnTargetUpdated="True"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
This method integrates seamlessly with your existing validation setup and keeps all UI logic in XAML.
2. Track Validation State in Your ViewModel (MVVM-Friendly)
If you're using MVVM, you can track the validation state directly in your ViewModel and bind to it. This works great if you need more control over when the success message appears (e.g., only after the user has finished typing).
First, add a boolean property to your ViewModel:
private bool _isInputValid; public bool IsInputValid { get => _isInputValid; set => SetProperty(ref _isInputValid, value); }
Then update this property when validation runs (you can hook into INotifyDataErrorInfo or trigger it manually after validation):
// Example: After validating the input var validationResult = new MyInputValidationRule().Validate(UserInput, null); IsInputValid = validationResult.IsValid;
Finally, bind to this property in your UI:
<StackPanel> <TextBox Text="{Binding UserInput, UpdateSourceTrigger=PropertyChanged}"> <!-- Your ValidationRule or INotifyDataErrorInfo setup --> </TextBox> <TextBlock Text="✓ Perfect! Your input checks out." Foreground="Green" Visibility="{Binding IsInputValid, Converter={StaticResource BooleanToVisibilityConverter}}"/> </StackPanel>
This approach keeps your validation logic decoupled from the UI, making it easier to test and maintain.
3. Create a Reusable Attached Property
For a more flexible, reusable solution, you can create an attached property to define success content for any control. This lets you add success messages to different controls without repeating template code.
First, define the attached property in code:
public static class ValidationSuccessHelpers { public static readonly DependencyProperty SuccessContentProperty = DependencyProperty.RegisterAttached( "SuccessContent", typeof(object), typeof(ValidationSuccessHelpers)); public static object GetSuccessContent(DependencyObject obj) { return obj.GetValue(SuccessContentProperty); } public static void SetSuccessContent(DependencyObject obj, object value) { obj.SetValue(SuccessContentProperty, value); } }
Then use it in your XAML style:
<Style TargetType="TextBox" x:Key="ValidatingTextBoxStyle"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <Grid> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer x:Name="PART_ContentHost"/> </Border> <!-- Host for success content --> <ContentControl x:Name="SuccessContentHost" Content="{TemplateBinding local:ValidationSuccessHelpers.SuccessContent}" Foreground="Green" Margin="0,22,0,0" Visibility="Collapsed"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="Validation.HasError" Value="False"> <Setter TargetName="SuccessContentHost" Property="Visibility" Value="Visible"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
Now you can apply this style to any TextBox and set custom success content:
<TextBox Style="{StaticResource ValidatingTextBoxStyle}" local:ValidationSuccessHelpers.SuccessContent="✓ All good to go!"> <!-- Your ValidationRule --> </TextBox>
All three methods work well—pick the one that fits your project's architecture and needs!
内容的提问来源于stack exchange,提问作者GreatDuke

