GoToState не работает для ControlTemplate в UserControl - PullRequest
1 голос
/ 30 июля 2010

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

Моя конечная цель - создать пользовательский элемент управления, который будет содержать два шаблона элемента управления. Квадрат и Круг. В зависимости от типа элемент управления будет отображать один или другой. Когда мышь входит в форму, непрозрачность изменится на 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);
    }
}

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

Спасибо

1 Ответ

2 голосов
/ 15 марта 2011

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

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

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

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

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

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

...