【问题标题】:UWP VisualStateManager.GoToState() Not WorkingUWP VisualStateManager.GoToState() 不工作
【发布时间】:2022-01-14 21:08:43
【问题描述】:

我创建了一个自定义控件 (ToggleIcon) 作为 CheckBox 的替代品,并且需要向其添加 IsChecked 属性,以便可以通过编程方式清除它。我尝试通过使用VisualStateManager.GoToState() 来完成此操作,但尽管执行时没有异常,但它不会改变状态。据我所知,它也总是返回 false。我在这里查看了其他几个问题,都说 VisualStateManager 必须位于 UserControl 的根目录中,但是当我移动它时,控件上没有任何显示。我不知道在哪里放置 VisualState XAML 以使其工作,有人对如何解决这个问题有任何想法吗?或者,是否有另一种方法来实现 IsChecked 并在状态更改时更新状态?我可以在单击/轻按控件时更新 IsChecked 属性,但无法使其反向工作(即当 IsChecked 更改时,VisualState 更改为 Checked 或 Unchecked)。

用户控件 XAML:

<UserControl
    x:Class="CustomControlScratchpad.ToggleIcon"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomControlScratchpad"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="128"
    d:DesignWidth="128">    
    <Grid>
        <CheckBox Width="32" Height="32">
            <CheckBox.Template>
                <ControlTemplate TargetType="CheckBox">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Tapped="Border_Tapped">
                        <Grid>
                            <BitmapIcon x:Name="UncheckedState" UriSource="{Binding UncheckedImage }" Opacity="0" ShowAsMonochrome="False" />
                            <BitmapIcon x:Name="CheckedState" UriSource="{Binding CheckedImage}" Opacity="0" ShowAsMonochrome="False" />
                        </Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CheckStates">
                                <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckedState" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unchecked">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="UncheckedState" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Border>
                </ControlTemplate>
            </CheckBox.Template>
        </CheckBox>
    </Grid>
</UserControl>

用户控制代码:

public bool IsChecked
        {
            get { return (bool)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }

        public static readonly DependencyProperty IsCheckedProperty =
            DependencyProperty.Register("IsChecked", typeof(bool), typeof(ToggleIcon), new PropertyMetadata(false));

        public ImageSource UncheckedImage
        {
            get { return (ImageSource)GetValue(UncheckedImageProperty); }
            set { SetValue(UncheckedImageProperty, value); }
        }

        public static readonly DependencyProperty UncheckedImageProperty =
            DependencyProperty.Register("UncheckedImage", typeof(ImageSource), typeof(ToggleIcon), new PropertyMetadata(new System.Uri("ms-appx:///Assets/default-unchecked.png")));

        public ImageSource CheckedImage
        {
            get { return (ImageSource)GetValue(CheckedImageProperty); }
            set { SetValue(CheckedImageProperty, value); } }

        public static readonly DependencyProperty CheckedImageProperty =
            DependencyProperty.Register("CheckedImage", typeof(ImageSource), typeof(ToggleIcon), new PropertyMetadata(new System.Uri("ms-appx:///Assets/default-checked.png")));

        public ToggleIcon()
        {
            this.InitializeComponent();
            DataContext = this;
        }

        private void Border_Tapped(object sender, TappedRoutedEventArgs e)
        {
            IsChecked = !IsChecked;
        }

测试按钮事件代码: 为了进行测试,我添加了一个按钮,当 IsChecked 更改时,该按钮可以将 VisualState 从一个切换到另一个。

        private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            //toggleIcon.IsChecked = !toggleIcon.IsChecked;
            if (toggleIcon.IsChecked)
                VisualStateManager.GoToState(toggleIcon, "Unchecked", false);
            else
                VisualStateManager.GoToState(toggleIcon, "Checked", false);
        }

【问题讨论】:

  • 您能尝试从 DoubleAnimation 中删除 Duration="0" 吗?我做了一个简单的 VisualState 来测试,代码可以在不添加 Duration 的情况下运行。
  • 这似乎奏效了,虽然我不明白为什么这会是一个问题....谢谢!如果您想将此作为解决方案发布,我会接受它作为正确答案。再次感谢!
  • 很高兴听到这个消息!我会发布它作为答案。

标签: c# uwp custom-controls dependency-properties visualstatemanager


【解决方案1】:

请从 VisualState 的 DoubleAnimation 中删除 Duration="0"。 DoubleAnimation 在 Duration 的 VisualState 中不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-17
    • 2021-07-22
    • 1970-01-01
    • 2018-11-04
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多