silverlight - ToggleButton 控件 VisualStateManager : Handling Multiple Hover States

标签 silverlight mvvm

引用我之前的一个问题( Silverlight MVVM Confusion: Updating Image Based on State ),我开始采用一种新方法。我离开了现有的问题,因为我不想肯定地说我的新方法是正确的答案(我仍然欢迎对我原来的问题发表评论)。

如果您阅读了我之前的问题,请随意跳过这一段:我正在尝试构建一个控件,该控件提供类似于音频播放按钮的功能。当应用程序处于“播放”模式时,应用程序应显示“Pause.png”图像。当它暂停时,它应该显示“Play.png”图像。当用户将鼠标悬停在控件上时,还有两个额外的图像可以说明两种状态(例如,“Play_Hover.png”和“Pause_Hover.png”)。状态由我的 View 模型中的 IsPlaying 属性决定。

我决定使用 ToggleButton 来根据当前状态确定要显示的图像。请记住,当 IsPlaying 为 false 时,将显示播放按钮,当为 true 时,将显示暂停按钮。因此,我想出了以下 XAML。它的工作原理除了悬停:

<UserControl x:Class="Foo.BarMyControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    mc:Ignorable="d"
    d:DesignHeight="100" d:DesignWidth="200">
    <UserControl.Resources>
        <Style x:Key="MyButtonStyle" TargetType="ToggleButton">
            <Setter Property="IsEnabled" Value="true"/>
            <Setter Property="IsTabStop" Value="true"/>
            <Setter Property="Background" Value="#FFA9A9A9"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="MinWidth" Value="5"/>
            <Setter Property="MinHeight" Value="5"/>
            <Setter Property="Margin" Value="0"/>
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CheckStates">
                                    <VisualState x:Name="Checked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Pause">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Play">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unchecked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Play">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Pause">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Image x:Name="Play" Source="/Foo.Bar;component/Resources/Icons/Bar/Play.png" />
                            <Image x:Name="Pause" Source="/Foo.Bar;component/Resources/Icons/Bar/Pause.png" Visibility="Collapsed" />
                            <Image x:Name="PlayHover" Source="/Foo.Bar;component/Resources/Icons/Bar/Play_Hover.png" Visibility="Collapsed" />
                            <Image x:Name="PauseHover" Source="/Foo.Bar;component/Resources/Icons/Bar/Pause_Hover.png" Visibility="Collapsed" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <ToggleButton Style="{StaticResource MyButtonStyle}" IsChecked="{Binding LiveEnabled}" Command="{Binding ChangeStatus}" Height="30" Width="30" />
    </Grid>
</UserControl>

您如何为两种状态提供不同的悬停图像?如果我将悬停状态添加到 CommonStates 组,我将能够仅考虑其中一种状态(选中或未选中)的悬停。

最佳答案

使用切换按钮,不可能有不同的悬停/鼠标悬停状态,因为这对按钮来说很常见。
常见状态是正常(您最初看到的)、鼠标悬停、按下和禁用

其他状态与已检查、未检查或中间状态有关。在这里,您可以为各种状态设置不同的图像等。鼠标悬停将始终回滚到普通状态。

如果您必须拥有此功能,您可以为此创建自己的自定义控件并根据事件状态处理鼠标悬停动画。这将需要在后端添加更多代码,因为您需要重新定义此对象的按钮类并插入各种状态的测试以允许为每个状态播放一组动画。这是可以做到的,我只是不知道是否值得付出那么多努力。

关于silverlight - ToggleButton 控件 VisualStateManager : Handling Multiple Hover States,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5045083/

相关文章:

c# - ScrollView 不是 MouseWheel 在不超过 Control 时滚动

silverlight - Silverlight Socket.ConnectAsync方法从不调用Completed事件

silverlight - Windows Phone 7 弹出窗口

c# - WPF 文本框性能

silverlight - EventToCommand SelectionChanged 在 Combobox 中传递参数

c# - Silverlight、DataTemplate、绑定(bind)到点击事件

c# - 如何从按下的列表框中获取项目的索引(列表包含与命令绑定(bind)而不是单击的按钮)

android - 如何使用具有相同 Fragment 的 4 个简单 ViewModel?

wpf - 数据显示之前,忙碌指示灯不显示

wpf - MVVM WPF 创建子元素