1

Je suis complètement perdu et j'apprécierais vraiment votre aide à ce sujet.GoToState ne fonctionne pas pour ControlTemplate dans UserControl

Mon objectif final est de créer un contrôle utilisateur qui contiendra deux modèles de contrôle. Carré et un cercle. Basé sur un type le contrôle affichera l'un ou l'autre. Lorsque la souris entre dans la forme, l'opacité devient 0.2.

La première partie fonctionne mais l'opacité ne change pas. L'événement est déclenché et un GoToState est appelé, mais sans résultat. Le Opacité reste 1.

Mon XAML:

<UserControl.Resources> 

    <ControlTemplate x:Key="TemplateSquare" TargetType="{x:Type local:KeyControl}"> 

     <Canvas x:Name="MainCanvas" VerticalAlignment="Center" HorizontalAlignment="Center"> 

      <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="CommonStates"> 
        <VisualState x:Name="Normal" /> 
        <VisualState x:Name="MouseOver"> 
         <Storyboard> 
          <DoubleAnimation Storyboard.TargetName="CenterRectangle" Storyboard.TargetProperty="(UIElement.Opacity)" Duration="0" To=".2"/> 
         </Storyboard> 
        </VisualState> 
       </VisualStateGroup> 
      </VisualStateManager.VisualStateGroups> 

      <Rectangle x:Name="CenterRectangle" Fill="Red" Width="100" Height="100"></Rectangle> 

     </Canvas> 

    </ControlTemplate>  
</UserControl.Resources> 
<!-- IF I MOVE THE CANVAS HERE THE OPACITY CHANGES ON MOUSE OVER --> 

Codebehind:

public partial class KeyControl : UserControl 
{ 
    private bool _isPressed = false; 
    private bool _isMouseOver = false; 

    public KeyControl() 
    { 
     InitializeComponent(); 

     this.Loaded += new RoutedEventHandler(KeyControl_Loaded); 
    } 


    private void KeyControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     //this will be set in the Type setter 
     this.Template = this.FindResource("TemplateSquare") as ControlTemplate; 

     this.MouseEnter += new MouseEventHandler(CorePart_MouseEnter); 
     this.MouseLeave += new MouseEventHandler(CorePart_MouseLeave); 

     GoToState(false); 
    } 

    private void GoToState(bool useTransitions) 
    { 
     if (_isPressed) 
      VisualStateManager.GoToState(this, "Pressed", useTransitions); 
     else if (_isMouseOver) 
      VisualStateManager.GoToState(this, "MouseOver", useTransitions); 
     else 
      VisualStateManager.GoToState(this, "Normal", useTransitions); 
    } 

    private void CorePart_MouseLeave(object sender, MouseEventArgs e) 
    { 
     _isMouseOver = false; 
     GoToState(true); 
    } 

    private void CorePart_MouseEnter(object sender, MouseEventArgs e) 
    { 
     _isMouseOver = true; 
     GoToState(true); 
    } 
} 

Quelqu'un peut-il s'il vous plaît me dire où le problème pourrait être?

Merci

Répondre

2

Le UserControl fait de son contenu l'élément « racine », qui est utilisé pour localiser les VisualStateGroups. Si vous utilisez réflecteur et regardez UserControl.StateGroupsRoot, vous verriez qu'il ressemble à:

internal override FrameworkElement StateGroupsRoot { 
    get { 
     return (base.Content as FrameworkElement); 
    } 
} 

Alors que FrameworkElement (et donc la plupart des autres éléments) utilisent:

internal virtual FrameworkElement StateGroupsRoot { 
    get { 
     return (this._templateChild as FrameworkElement); 
    } 
} 

Lorsque vous définissez la propriété du modèle, la propriété Content sera toujours nulle. Lorsque vous déplacez le canevas en dessous des ressources, vous définissez la propriété Content. Ainsi, les groupes d'états visuels peuvent être trouvés dans ce cas.

Vous pouvez contourner ce problème en changeant votre contrôle directement à partir de ContentControl et en ignorant UserControl. Changez simplement les références UserControl à ContentControl dans votre code XAML et code-behind.