1

Я полностью потерян, и я был бы очень признателен за вашу помощь в этом.GoToState не работает для ControlTemplate в UserControl

Моя конечная цель - создать пользовательский элемент управления, который будет содержать два шаблона управления. Площадь и круг. На основе типа элемент управления будет отображать тот или иной. Когда мышь входит в форму, Opacity изменится на 0.2.

Первая часть работает, но непрозрачность не меняется. Событие запускается и вызывается GoToState, но без результата. Непрозрачность остается 1.

Мой 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); 
    } 
} 

Может кто-нибудь пожалуйста, скажите мне, где эта проблема может быть?

Спасибо

ответ

2

UserControl делает это Content элемент «корень», который используется для обнаружения VisualStateGroups. Если вы используете отражатель и посмотреть на UserControl.StateGroupsRoot, вы бы увидели это выглядит следующим образом:

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

Хотя FrameworkElement (и, таким образом, большинство других элементов) используют:

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

При установке свойства шаблона, свойство Content все равно будет null. Когда вы перемещаете холст ниже Ресурсов, вы устанавливаете свойство Content. Таким образом, визуальные группы состояний можно найти в этом случае.

Вы можете обойти это, изменив свой контроль непосредственно из ContentControl и обойдя UserControl. Просто измените ссылки UserControl на ContentControl на ваш XAML и код.