C# 重新启用RadioButton后不会触发选中的VisualState

C# 重新启用RadioButton后不会触发选中的VisualState,c#,wpf,xaml,radio-button,visualstates,C#,Wpf,Xaml,Radio Button,Visualstates,我正在使用一个自定义的RadioButton控件,它允许用户根据所选RadioButton给出1到5之间的评级 但是,在我的应用程序中,有时会禁用5个单选按钮,然后重新启用。发生这种情况时,选中单选按钮的VisualState不会激活。相反,所有5个单选按钮显示为正常状态 为什么会这样?我如何解决这个问题? 下面是我正在使用的单选按钮的示例 如果我从选择第一组5个单选按钮开始,然后进行选择,那么所有内容都可能显示为上图所示 但是,如果我选择第二组5个单选按钮,我的控件设计为第一组将禁用。这工作正

我正在使用一个自定义的RadioButton控件,它允许用户根据所选RadioButton给出1到5之间的评级

但是,在我的应用程序中,有时会禁用5个单选按钮,然后重新启用。发生这种情况时,选中单选按钮的VisualState不会激活。相反,所有5个单选按钮显示为正常状态

为什么会这样?我如何解决这个问题? 下面是我正在使用的单选按钮的示例

如果我从选择第一组5个单选按钮开始,然后进行选择,那么所有内容都可能显示为上图所示

但是,如果我选择第二组5个单选按钮,我的控件设计为第一组将禁用。这工作正常,第二组可以正常启用。之后,如果我再次选择第一个组,每个单选按钮都将以正常的VisualState显示。这是一个问题,因为我的程序知道在幕后1仍然被检查。选中的VisualState未被触发,因此看起来如下所示:

这里的目标是,选中的VisualState将恢复第一个图像中显示的状态

以下是VisualStates对应的XAML代码:


显然,问题是我在两个不同的VisualState组中使用相同的目标属性

为了获得所需的效果,即在重新启用后显示选中的行为,我创建了另一个覆盖原始椭圆的椭圆

原始椭圆完全不透明,其填充/笔划属性仅由CheckState组修改

新椭圆最初为完全透明不透明度=0,但禁用状态会导致不透明度更改为完全不透明

此新椭圆淡入视图并覆盖原始椭圆,该椭圆显示选中/未选中状态的外观。这会导致RadioButton的整体结果显示为禁用

这修复了OP中描述的问题,但它引入了一个新问题:从禁用状态到选中状态的转换是即时的。可以通过将此VisualTransition包含在CommonStates组中来解决此问题:

请注意,此椭圆包含使用OP的禁用VisualState的填充/笔划属性

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualState Name="Normal"/>
        <VisualState Name="Disabled">
            <Storyboard>
                <ColorAnimation Storyboard.TargetName="FillBrush" Storyboard.TargetProperty="Color" To="#FFEEEEEE" Duration="0"/>
                <ColorAnimation Storyboard.TargetName="StrokeBrush" Storyboard.TargetProperty="Color" To="#FF777777" Duration="0"/>
                <DoubleAnimation Storyboard.TargetName="MoodEllipse" Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0"/>
                <ColorAnimation Storyboard.TargetName="Presenter" Storyboard.TargetProperty="(TextBlock.Foreground).Color" To="#FF777777" Duration="0"/>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>
    <VisualStateGroup x:Name="CheckStates">
        <VisualState Name="Checked">
            <Storyboard>
                <ParallelTimeline>
                    <ColorAnimation Storyboard.TargetName="FillBrush" Storyboard.TargetProperty="Color" To="#FFC5F5FF" Duration="0:0:0.05"/>
                    <ColorAnimation Storyboard.TargetName="StrokeBrush" Storyboard.TargetProperty="Color" To="#FF12394F" Duration="0:0:0.05"/>
                    <DoubleAnimation Storyboard.TargetName="MoodEllipse" Storyboard.TargetProperty="StrokeThickness" To="2" Duration="0:0:0.05"/>
                </ParallelTimeline>
            </Storyboard>
        </VisualState>
        <VisualState Name="Unchecked"/>
        <VisualState Name="Indeterminate"/>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type RadioButton}}, Path=IsChecked}">
<VisualTransition From="Disabled" To="Checked" GeneratedDuration="0:0:0.25"/>
<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualStateGroup.Transitions>
            <VisualTransition From="Disabled" To="Checked" GeneratedDuration="0:0:0.25"/>
        </VisualStateGroup.Transitions>
        <VisualState Name="Normal"/>
        <VisualState Name="Disabled">
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName="EllipseOverlay" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.15"/>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>
    <VisualStateGroup x:Name="CheckStates">
        <VisualState Name="Checked">
            <Storyboard>
                <ParallelTimeline>
                    <ColorAnimation Storyboard.TargetName="FillBrush" Storyboard.TargetProperty="Color" To="#FFC5F5FF" Duration="0:0:0.05"/>
                    <ColorAnimation Storyboard.TargetName="StrokeBrush" Storyboard.TargetProperty="Color" To="#FF12394F" Duration="0:0:0.05"/>
                    <DoubleAnimation Storyboard.TargetName="MoodEllipse" Storyboard.TargetProperty="StrokeThickness" To="2" Duration="0:0:0.05"/>
                </ParallelTimeline>
            </Storyboard>
        </VisualState>
        <VisualState Name="Unchecked"/>
        <VisualState Name="Indeterminate"/>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="EllipseOverlay" StrokeThickness="1" Opacity="0" Fill="#FFEEEEEE" Stroke="#FF777777"/>