重新启用RadioButton后,不会触发已检查的VisualState

时间:2014-09-12 05:07:17

标签: c# wpf xaml radio-button visualstates

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

但是,我的应用程序中有时会禁用5 RadioButtons,然后重新启用。发生这种情况时,已检查 VisualState的{​​{1}}不会激活。相反,所有5 RadioButton都显示为正常状态。

为什么会这样?我该如何解决这个问题?

以下是我正在使用的RadioButtons的示例。

RadioButton VisualStates

如果我首先选择第一组5 RadioButtons并进行选择,那么所有内容都可能会显示为上图。

但是,如果我选择第二组5 RadioButtons,我的控件设计为第一组将禁用。这工作正常,第二组正常启用。之后,如果我再次选择第一个组,则每个RadioButtons都会显示 Normal VisualState 。这是一个问题,因为我的程序知道幕后的#1 仍然是已检查 Checked VisualState 未被触发,因此它看起来像这样:

RadioButton VisualStates (error)

此处的目标是已检查 Radiobutton将在第一张图片中显示时恢复。

以下是VisualState

的相应XAML代码
VisualStates

这个XAML代码似乎与<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> 的使用方式有关,但我认为它一定有问题。

我引用了这些页面:

作为一些补充说明,我注意到,如果点击其中一个未选中 VisualStates,则可以触发已检查 VisualState。在这一点上,一切都正常 - 直到RadioButtons组被禁用&amp;重新启用。

另外,当我在未选中 RadioButtons中没有包含空未选中 VisualState时,我对已检查 VisualState的行为更为陌生。以上是XAML代码。

有关VisualStates行为奇怪的原因的任何见解都将非常感激。非常感谢!

修改

我不确定这是否重要,但RadioButtons组被禁用,因为它们位于StackPanels IsEnabled属性绑定到外部RadioButton' s IsChecked财产:

<StackPanel IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type RadioButton}}, Path=IsChecked}">

1 个答案:

答案 0 :(得分:1)

显然,问题是我在两个不同的VisualStateGroupsyet I'm not sure why this causes the problem中使用相同的目标属性。

为了获得所需的效果,即在重新启用后显示已检查的行为,我创建了另一个Ellipse,它与原始Ellipse重叠

原始Ellipse完全不透明,只有 CheckStates 组修改了填充/笔触属性。

新的Ellipse最初是完全透明的(Opacity="0"),但已禁用状态会导致不透明度变为完全不透明。

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

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

<VisualTransition From="Disabled" To="Checked" GeneratedDuration="0:0:0.25"/>

以下是用于解决问题的最终XAML:

<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之后显示Ellipse,导致新效果在不透明度增加时显示在顶部。以下是新的Ellipse

<Ellipse x:Name="EllipseOverlay" StrokeThickness="1" Opacity="0" Fill="#FFEEEEEE" Stroke="#FF777777"/>

请注意,此Ellipse包含使用OP 已禁用 VisualState填充/笔触属性。