VisualStateGroup в пользовательском элементе управления не работает - PullRequest
1 голос
/ 14 января 2020

Использование VisualStateGroup общих имен состояний не влияет на пользовательский интерфейс в моем ControlTemplate.

В других примерах стиля все имена одинаковых состояний прекрасно работают, как я вижу в исходном коде Microsoft Toolkit на github. , поэтому я думаю, что это потому, что я использую пользовательский целевой элемент управления.

TargetType = " local: VolumetricButton "

Можно ли исправить этот код?
А если нет, как правильно добавить и обработать «CommonStates» в вашем ControlTemplate?

Generi c .xaml


<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Components">

    <Style TargetType="local:VolumetricButton">
        <Setter Property="Template" Value="{StaticResource VolumetricButtonTemplate}" />
    </Style>

    <ControlTemplate x:Key="VolumetricButtonTemplate" TargetType="local:VolumetricButton">
        <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualStateGroup.Transitions>
                        <VisualTransition To="PointerOver" 
                                          GeneratedDuration="0:0:0.5"/>
                    </VisualStateGroup.Transitions>

                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="PointerOver">
                        <Storyboard>
                            <ColorAnimation Storyboard.TargetName="BackBrush" 
                                            Storyboard.TargetProperty="Color" To="Red" />
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Rectangle x:Name="BackgroundRectangle" RadiusX="2" RadiusY="2">
                <Rectangle.Fill>
                    <SolidColorBrush x:Name="BackBrush" Color="Green"/>
                </Rectangle.Fill>
            </Rectangle>
        </Grid>
    </ControlTemplate>
</ResourceDictionary>


VolumetricButton.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235

namespace Components
{
    [TemplatePart(Name = BackgroundRectangleName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RootGridName, Type = typeof(Grid))]
    public sealed class VolumetricButton : Control
    {
        private const string BackgroundRectangleName = "BackgroundRectangle";
        private const string RootGridName = "RootGrid";

        private Rectangle BackgroundRectangle;
        private Grid RootGrid;

        public VolumetricButton()
        {
            this.DefaultStyleKey = typeof(VolumetricButton);

            // 
            // Set core events
            //
            this.SizeChanged += OnThisSizeChanged;
        }

        /// <inheritdoc/>
        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            //
            // New code here
            // 

            // Find and set RootGrid
            RootGrid = GetTemplateChild(RootGridName) as Grid;

            // Find and set BackgroundRectangle
            BackgroundRectangle = GetTemplateChild(BackgroundRectangleName) as Rectangle;
        }

        private void OnThisSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (BackgroundRectangle != null
                && RootGrid != null)
            {
                BackgroundRectangle.Width = RootGrid.ActualWidth;
                BackgroundRectangle.Height = RootGrid.ActualHeight;
            }
        }
    }
}

Best regards,

Roman

1 Ответ

1 голос
/ 14 января 2020

В настоящее время вы только определяете состояние PointerOver, но способ его запуска не определен.

Попробуйте это:

  1. Добавьте события, связанные с указателем, в OnApplyTemplate
protected override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    // ...

    RootGrid.PointerEntered += RootGrid_PointerEntered;
    RootGrid.PointerExited += RootGrid_PointerExited;
}
Полное переключение состояний в методах обработки событий
private void RootGrid_PointerExited(object sender, PointerRoutedEventArgs e)
{
    VisualStateManager.GoToState(this, "Normal", true);
}

private void RootGrid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    VisualStateManager.GoToState(this, "PointerOver", true);
}

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...