WPF列表视图行背景闪烁效果

4

我使用带有ListView控件的WPF。

当某个参数设置为True时,我希望ListView中的行具有闪烁动画。

我有以下代码可以工作,但是当鼠标移到带有动画的行上时,动画会停止。

我希望动画继续播放,直到该参数被改回False。

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="IsSelected" Value="{Binding Selected}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding DoBlink}" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard FillBehavior="Stop">
                            <ColorAnimation Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" 
                                            From="Blue" To="LightBlue" Duration="0:0:0.2"
                                            AutoReverse="True" RepeatBehavior="Forever" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListView.ItemContainerStyle>

我觉得当你的鼠标悬停时,它会触发背景变化。你可能需要在Blend中展开控件并查看是否如此。另一个可能性是有东西覆盖在你的背景上,它可能仍然在后面闪烁。用Snoop来看一下。 - Philippe Lavoie
1
似乎ListView默认的鼠标悬停动画正在阻止您... 您可以通过Blend来控制它。 - Bathineni
2个回答

8
这种情况需要使用MultiDataTrigger。尝试使用以下代码:
<Style
        TargetType="{x:Type ListViewItem}">
        <Setter Property="IsSelected" Value="{Binding Selected}"/>
        <Setter
            Property="Template">
            <Setter.Value>
                <ControlTemplate
                    TargetType="{x:Type ListViewItem}">
                    <Border
                        Name="Border"
                        SnapsToDevicePixels="True"
                        Padding="2,2,2,2"
                        Background="Transparent">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition
                                    Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsMouseOver}"
                                    Value="True" />
                     <Condition
                        Binding="{Binding DoBlink}"
                        Value="True" />
                            </MultiDataTrigger.Conditions>
                            <MultiDataTrigger.EnterActions>
                                <BeginStoryboard
                                    Name="Flash">
                                    <Storyboard
                                        FillBehavior="Stop">
                                        <ColorAnimation
                                            Storyboard.TargetProperty="Background.Color"
                                            Storyboard.TargetName="Border"
                                            From="Blue"
                                            To="LightBlue"
                                            Duration="0:0:0.2"
                                            AutoReverse="True"
                                            RepeatBehavior="Forever" />

                                    </Storyboard>
                                </BeginStoryboard>
                            </MultiDataTrigger.EnterActions>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition
                                    Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsMouseOver}"
                                    Value="False" />
                                <Condition
                                    Binding="{Binding DoBlink}"
                                    Value="True" />
                            </MultiDataTrigger.Conditions>
                            <MultiDataTrigger.EnterActions>
                                <StopStoryboard
                                    BeginStoryboardName="Flash" />
                            </MultiDataTrigger.EnterActions>
                        </MultiDataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style> 

你还需要使用MultiDataTrigger来停止动画,当条件匹配时,你希望它停止。
编辑:您可以在这里阅读有关MultiDataTriggers的信息。
编辑2:我已经修改了代码,使其适用于控件模板,并添加了一组条件,在选择另一个项目时停止动画。
编辑3:删除不必要的IsSelected条件。

我遇到了一个异常:“必须为'Binding'提供非空值。”,我发现这是因为“<Condition Property =”IsMouseOver" Value ="True"/>”,我将其替换为<Condition Binding = "{Binding RelativeSource = {RelativeSource Self},Path = IsMouseOver}" Value = "True"/>,但现在它根本不触发。 - RuSh
看起来像是列表视图的默认样式在妨碍你。使用相同的代码,但将你的Storyboard.TargetProperty更改为Control.Foreground。我成功让它闪烁了。 - Scott Boettger
新的带有控件模板的示例应该适用于您。 - Scott Boettger
谢谢,代码仍然无法工作。应用更改后,ListView行不会闪烁,也不会显示行列/数据。而且只有在选择项目时才会闪烁,我希望它在参数更改之前一直闪烁。 - RuSh
删除IsSelected触发条件。我将从我的示例代码中删除它。 - Scott Boettger
如果您的数据没有显示,可能是因为您设置了listviewitem的内容字段的方式不正确。 - Scott Boettger

2
使用StyleSnooperPeter Blois' Snoop来检查MouseOver的操作。我怀疑你有一个MouseOver处理程序会覆盖你的StoryBoard。你可以为你的ListBox项(或其中的某些内容)创建自己的样式,不包括MouseOver处理程序,或者使用MultiTrigger,在其他条件为真时不执行MouseOver。

1
Scott的下面的答案给出了一个很好的例子。如果您使用他的代码,请随意接受他的答案。 - Ed Bayiates

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接