首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义控件中的VisualStateGroup无法工作

自定义控件中的VisualStateGroup无法工作
EN

Stack Overflow用户
提问于 2020-01-14 09:13:10
回答 1查看 209关注 0票数 1

使用VisualStateGroup公共状态名称对我的ControlTemplate中的UI没有任何影响。

在其他样式的示例中,相同的状态名称都能很好地工作,正如我在github上的Microsoft源代码中看到的那样,所以我认为这是因为我使用了一个自定义的目标控件。

TargetType="local:VolumetricButton

有可能修复这段代码吗?

如果不是,如何在CommonStates中正确地添加和处理“ControlTemplate

Generic.xaml

代码语言:javascript
复制
<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

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-14 11:00:34

您目前只定义PointerOver的状态,但是没有定义如何触发状态。

试试这个:

OnApplyTemplate

  1. 添加指针相关事件

代码语言:javascript
复制
protected override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    // ...

    RootGrid.PointerEntered += RootGrid_PointerEntered;
    RootGrid.PointerExited += RootGrid_PointerExited;
}

事件处理方法中的

  1. 完全状态切换

代码语言:javascript
复制
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);
}

诚挚的问候。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59730628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档