VisualStateManager无法控制扩展Button

时间:2018-02-09 11:29:56

标签: wpf button visualstatemanager

我已经使用一些新属性扩展了Button。 我还重新定义了这样的模板:

public class CustomButton : Button
{
    #region ShowLabel
    public bool ShowLabel
    {
        get { return (bool)GetValue( ShowLabelProperty ); }
        set { SetValue( ShowLabelProperty, value ); }
    }

    // Using a DependencyProperty as the backing store for ShowLabel.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ShowLabelProperty =
        DependencyProperty.Register( nameof( ShowLabel ), typeof( bool ), typeof( CustomButton ), new PropertyMetadata( true ) );
    #endregion

    #region LabelText
    public string LabelText
    {
        get { return (string)GetValue( LabelTextProperty ); }
        set { SetValue( LabelTextProperty, value ); }
    }

    // Using a DependencyProperty as the backing store for LabelText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty LabelTextProperty =
        DependencyProperty.Register( nameof( LabelText ), typeof( string ), typeof( CustomButton ) );
    #endregion

    static CustomButton()
    {
        Type ownerType = typeof( CustomButton );

        DefaultStyleKeyProperty.OverrideMetadata( ownerType,
            new FrameworkPropertyMetadata( ownerType ) );

        StyleProperty.OverrideMetadata( ownerType,
            new FrameworkPropertyMetadata( null, ( depObj, baseValue ) =>
            {
                var element = depObj as FrameworkElement;
                if( element != null && baseValue == null )
                    baseValue = element.TryFindResource( ownerType );

                return baseValue;
            } ) );
    }             
}

<Style x:Key="{x:Type cc:CustomButton}" TargetType="{x:Type cc:CustomButton}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Foreground" Value="#FF0072C6"/>
    <Setter Property="BorderBrush" Value="#FF0072C6"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="FontSize" Value="13"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cc:CustomButton}">

                <DockPanel>
                    <Grid DockPanel.Dock="Top" x:Name="grid" Background="Black">

                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />

                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Green"/>
                                    </Storyboard>
                                </VisualState>

                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Red"/>
                                    </Storyboard>
                                </VisualState>

                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Gray"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Ellipse x:Name="ellipse" Stroke="{TemplateBinding BorderBrush}" Width="64" Height="64"
                                StrokeThickness="3" />

                        <ContentPresenter
                                x:Name="contentPresenter"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                Margin="{TemplateBinding Padding}"/>
                    </Grid>

                    <TextBlock DockPanel.Dock="Top" Text="{TemplateBinding LabelText}" FontSize="{TemplateBinding FontSize}" Foreground="{TemplateBinding Foreground}"
                               FontFamily="{TemplateBinding FontFamily}" FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}"
                               FontStretch="{TemplateBinding FontStretch}" Visibility="{calcBinding:Binding ShowLabel, RelativeSource={RelativeSource TemplatedParent}}"
                               VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                               HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                </DockPanel>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

但是,当鼠标经过按钮或按钮被禁用时,VisualState不会更新。

问题是什么?

1 个答案:

答案 0 :(得分:1)

您应该将VisualStates应用于DockPanel,即您尝试应用动画的Grid的父级:

<ControlTemplate TargetType="{x:Type cc:CustomButton}">
    <DockPanel>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal" />

                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Green"/>
                    </Storyboard>
                </VisualState>

                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Red"/>
                    </Storyboard>
                </VisualState>

                <VisualState x:Name="Disabled">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="Background.Color" To="Gray"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid DockPanel.Dock="Top" x:Name="grid" Background="Black">

            <Ellipse x:Name="ellipse" Stroke="{TemplateBinding BorderBrush}" Width="64" Height="64"
                                StrokeThickness="3" />

            <ContentPresenter
                                x:Name="contentPresenter"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                Margin="{TemplateBinding Padding}"/>
        </Grid>

        <TextBlock DockPanel.Dock="Top" Text="{TemplateBinding LabelText}" FontSize="{TemplateBinding FontSize}" Foreground="{TemplateBinding Foreground}"
                               FontFamily="{TemplateBinding FontFamily}" FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}"
                               FontStretch="{TemplateBinding FontStretch}" Visibility="{calcBinding:Binding ShowLabel, RelativeSource={RelativeSource TemplatedParent}}"
                               VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                               HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
    </DockPanel>
</ControlTemplate>

没有名为&#34; grid&#34;的元素在Grid本身。