2010-11-12 3 views
13

Pourquoi n'y a-t-il pas de texte d'info-bulle sur les erreurs?Erreurs de validation WPF: Définition d'une info-bulle avec un message d'erreur

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="Validation.ErrorTemplate"> 
     <Setter.Value> 
      <ControlTemplate> 
       <StackPanel> 
        <Border ...> 
         <AdornedElementPlaceholder ... 
          ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> 
        </Border> 
        ... 
       </StackPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Je remarque aussi que

<AdornedElementPlaceholder ... 
    ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> 

échoue mais les ci-dessous, même avec proprement déroulée la même liaison, pourquoi il en est ainsi? AdornedElementPlaceholder ne fait pas référence à la zone de texte? Même si ce n'est pas le cas, une info-bulle ne devrait-elle pas apparaître quelque part?

<Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="True"> 
     <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> 
    </Trigger> 
</Style.Triggers> 

Répondre

4

Vous ne pouvez pas placer une info-bulle sur le AdornedElementPlaceholder, je ne pense pas qu'il soit visible du tout, il est juste de réserver l'espace pour celui qui l'utilise (dans votre cas une zone de texte). En regardant l'arbre visuel avec Snoop, nous pouvons voir que le TemplatedAdorner se retrouve à un endroit différent dans le VisualTree que dans le TextBox, donc il y aura maintenant moyen de trouver le TextBox à partir de VisualTree. Nous pouvons le trouver via AdornedElement, mais nous ne serons toujours pas en mesure de définir une info-bulle.

alt text

La seule chose visible ici dans le TemplatedAdorner est la frontière. La frontière connaît son enfant - le TemplatedAdorner - qui connaît à son tour son AdornedElement - le TextBox. Nous pouvons donc définir l'info-bulle pour la bordure avec ceci. (Cependant, cette liaison semble ne pas mettre à jour l'info-bulle de la frontière. Il fonctionne quand je regarde avec Snoop et après qu'il affiche.) Alors

<Border BorderBrush="Red" 
     BorderThickness="4" 
     ToolTip="{Binding RelativeSource={RelativeSource self}, 
        Path=Child.AdornedElement.(Validation.Errors)[0].ErrorContent}"> 

, la zone de texte a son AttachedProperty de validation où nous pouvons trouver le ErrorContent donc il doit définir son propre ToolTip comme vous l'avez fait dans votre dernier exemple, sinon cela ne marchera pas.

+2

Solution est très bien, mais pour éviter des exceptions dans la fenêtre de votre Output.Debug je ferais votre info-bulle de liaison info-bulle = "{Binding RelativeSource = {RelativeSource self}, Path = Child.AdornedElement. (Validation.Errors) .CurrentItem.ErrorContent} " – Dude0001

17

Je sais que je suis en retard, mais permettez-moi de partager une solution que j'ai trouvé en étudiant cette question: WPF custom validator with tooltip.

Dans sa forme la plus simple ce ErrorTemplate montre seulement Tooltip avec le ErrorContent pour toute AdornedElement.

<ControlTemplate x:Key="validationTemplate"> 
    <Grid Background="Transparent" 
      ToolTip="{Binding Path=/ErrorContent}"> 
     <AdornedElementPlaceholder /> 
    </Grid> 
</ControlTemplate> 

Mais bien sûr, vous pouvez le décorer comme vous le souhaitez. avec Tooltip pour juste un marqueur.

<ControlTemplate x:Key="validationTemplate"> 
    <Grid> 
     <Ellipse Fill="Red" Opacity="0.8" Width="10" Height="10" 
       HorizontalAlignment="Right" VerticalAlignment="Top" 
       ToolTip="{Binding Path=/ErrorContent}" /> 
     <AdornedElementPlaceholder /> 
    </Grid> 
</ControlTemplate> 

Mettre ce Template dans Resources et tout ce que vous avez à faire est le réglage de la Validation.ErrorTemplate.

Validation.ErrorTemplate="{StaticResource validationTemplate}" 

Même cette gâchette agaçante n'est plus nécessaire.

<Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="True"> 
     <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> 
    </Trigger> 
</Style.Triggers> 
+1

C'est une bonne idée; Malheureusement, votre première solution placera une superposition (transparente) sur toute la zone de texte, empêchant l'utilisateur de la focaliser et de corriger l'erreur. – poke

+0

@poke Vous avez raison. La première solution n'est utile que pour les contrôles montrant une erreur. Mais peut-être que la deuxième solution est de toute façon ce que vous voulez. – LPL

+0

La deuxième solution fonctionne correctement pour un TextBox, mais pas pour un contrôle ComboBox. Je ne peux pas du tout cliquer sur ComboBox si j'ai IsHitTestVisible défini sur true, ce qui semble être nécessaire pour que l'info-bulle fonctionne. Des pensées? –