简体   繁体   中英

Event triggered only when a condition occurs

what I'm trying to do is basically set a condition for an event to be triggered. I have this custom control where there is a Grid that has the following behavior:

  • MouseOver : the Opacity of another Grid (from now on called priorityFlag and placed over the triggered one, called priorityGrid ) is set from 0 to 100 and its Width is set from 10 to 20 .
  • MouseLeave : the Opacity of the priorityFlag is set back to 0 and its Width back to 10 .
  • MouseUp : the user clicks on one of the priorityFlag 's rows and, through a command, it changes the color of the priorityGrid . When the click ends, the priorityFlag 's Opacity goes to 0 and its Width is set back to 10 (basically the same behavior of the MouseLeave event).

It works just fine, but when the MouseUp occurs and the user leaves the priorityGrid , the MouseLeave event gets triggered and I obtain the following behavior (you can see me hovering a couple times over the priorityGrid and then changing the priority color):

事件

As you can see, there is an annoying flickering effect caused by the MouseLeave event.

What I'd like to know is: can I condition a trigger in order to avoid the properties changes? It seems to me that there is no parameter allowing me to do so...

Here is the custom control XAML code:

<UserControl x:Class="CSB.Tasks.TaskListItemControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CSB.Tasks"
         xmlns:core="clr-namespace:CSB.Tasks.Core;assembly=CSB.Tasks.Core"
         mc:Ignorable="d"
         d:DesignHeight="70" 
         d:DesignWidth="400">

<!-- Custom control that represents a Task. -->
<UserControl.Resources>
    <!-- The control style. -->
    <Style x:Key="ContentStyle" 
           TargetType="{x:Type ContentControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ContentControl}">

                    <Border x:Name="ContainerBorder" 
                            BorderBrush="{StaticResource LightVoidnessBrush}"
                            Background="{StaticResource VoidnessBrush}"
                            BorderThickness="1"
                            Margin="2">

                        <Border.InputBindings>
                            <MouseBinding MouseAction="LeftClick" 
                                          Command="{Binding SelectTaskCommand}"/>
                        </Border.InputBindings>

                        <!-- The grid that contains the control. -->
                        <Grid Name="ContainerGrid" 
                              Background="Transparent">

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>

                            <!-- Border representing the priority state of the Task:
                                 The color is defined by a ValueConverter according to the PriorityLevel of the Task object. -->
                            <Border Grid.Column="0"
                                    Name="priorityFlag"
                                    Width="10"
                                    HorizontalAlignment="Left"
                                    Background="{Binding Priority, Converter={local:PriorityLevelToRGBConverter}, FallbackValue={StaticResource EmerlandBrush}}">

                                <Grid Name="priorityGrid"
                                      Opacity="0"
                                      HorizontalAlignment="Left"
                                      Width="20">

                                    <Grid.RowDefinitions>
                                        <RowDefinition/>
                                        <RowDefinition/>
                                        <RowDefinition/>
                                    </Grid.RowDefinitions>

                                    <Border Grid.Row="0"
                                            Name="lowPriority"
                                            Background="{Binding Source={x:Static core:PriorityLevel.Low}, Converter={local:PriorityLevelToRGBConverter}}">

                                        <Border.InputBindings>
                                            <MouseBinding MouseAction="LeftClick"
                                                          Command="{Binding SetLowPriorityCommand}"/>
                                        </Border.InputBindings>

                                    </Border>
                                    <Border Grid.Row="1"
                                            Name="mediumPriority"
                                            Background="{Binding Source={x:Static core:PriorityLevel.Medium}, Converter={local:PriorityLevelToRGBConverter}}">

                                        <Border.InputBindings>
                                            <MouseBinding MouseAction="LeftClick"
                                                          Command="{Binding SetMediumPriorityCommand}"/>
                                        </Border.InputBindings>

                                    </Border>
                                    <Border Grid.Row="2"
                                            Name="highPriority"
                                            Background="{Binding Source={x:Static core:PriorityLevel.High}, Converter={local:PriorityLevelToRGBConverter}}">

                                        <Border.InputBindings>
                                            <MouseBinding MouseAction="LeftClick"
                                                          Command="{Binding SetHighPriorityCommand}"/>
                                        </Border.InputBindings>

                                    </Border>

                                    <Grid.Triggers>
                                        <EventTrigger RoutedEvent="MouseEnter">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <DoubleAnimation Storyboard.TargetName="priorityGrid" Storyboard.TargetProperty="Opacity" From="0" To="100" Duration="0:0:0:0.1"/>
                                                    <DoubleAnimation Storyboard.TargetName="priorityFlag" Storyboard.TargetProperty="Width" From="10" To="20" Duration="0:0:0:0.1"/>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>

                                        <EventTrigger RoutedEvent="MouseLeave">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <DoubleAnimation Storyboard.TargetName="priorityGrid" Storyboard.TargetProperty="Opacity" From="100" To="0" Duration="0:0:0:0.1"/>
                                                    <DoubleAnimation Storyboard.TargetName="priorityFlag" Storyboard.TargetProperty="Width" From="20" To="10" Duration="0:0:0:0.1"/>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>

                                        <EventTrigger RoutedEvent="MouseUp">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <DoubleAnimation Storyboard.TargetName="priorityGrid" Storyboard.TargetProperty="Opacity" From="100" To="0" Duration="0:0:0:0.1"/>
                                                    <DoubleAnimation Storyboard.TargetName="priorityFlag" Storyboard.TargetProperty="Width" From="20" To="10" Duration="0:0:0:0.1"/>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>

                                    </Grid.Triggers>

                                </Grid>

                            </Border>

                            <!-- Border containing the Task's informations. -->
                            <Border Grid.Column="0"
                                    Margin="20 0 0 0"
                                    Padding="5">
                                <StackPanel>
                                    <!-- The title of the Task. -->
                                    <TextBlock Text="{Binding Title}" 
                                               FontSize="{StaticResource TaskListItemTitleFontSize}" 
                                               Foreground="{StaticResource DirtyWhiteBrush}"/>

                                    <!-- The customer the Taks refers to. -->
                                    <TextBlock Text="{Binding Customer}" 
                                               Style="{StaticResource TaskListItemControlCustomerTextBlockStyle}"/>

                                    <!-- The description of the Task. -->
                                    <TextBlock Text="{Binding Description}"
                                               TextTrimming="WordEllipsis"
                                               Foreground="{StaticResource DirtyWhiteBrush}"/>
                                </StackPanel>
                            </Border>

                            <!-- Border that contains the controls for the Task management. -->
                            <Border Grid.Column="2"
                                    Padding="5">

                                <!-- Selection checkbox of the Task. -->
                                <CheckBox VerticalAlignment="Center" 
                                          IsChecked="{Binding IsSelected}"/>
                            </Border>

                        </Grid>

                    </Border>

                    <!-- Template triggers. -->
                    <ControlTemplate.Triggers>

                        <DataTrigger Binding="{Binding IsSelected}" Value="True">
                            <Setter Property="Background" TargetName="ContainerBorder" Value="{StaticResource OverlayVoidnessBrush}"/>
                            <Setter Property="BorderBrush" TargetName="ContainerBorder" Value="{StaticResource PeterriverBrush}"/>
                        </DataTrigger>

                        <EventTrigger RoutedEvent="MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0:0" To="{StaticResource OverlayVoidness}" Storyboard.TargetName="ContainerGrid" Storyboard.TargetProperty="Background.Color"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>

                        <EventTrigger RoutedEvent="MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0:0" To="Transparent" Storyboard.TargetName="ContainerGrid" Storyboard.TargetProperty="Background.Color"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>

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

<!-- Content of the control: assignment of the DataContext for design-time testing. -->
<ContentControl d:DataContext="{x:Static local:TaskListItemDesignModel.Instance}" 
                Style="{StaticResource ContentStyle}"/>

Can anyone help me? Thank you in advance for the help.

It looks like that when you trigger the MouseUp trigger it also triggers the MouseOver trigger. Therefore, the priorityFlag's Width is changed to 20 twice during the same time. Obviously, it is twice changed back,when you move the Mouse away, once (i) via MouseLeave and once (ii) via MouseUp end of the click, also basically during the same time, which causes the flickering.

You may define a private flag property in the class containing all the mouse events, which would be set to true, when the priorityFlag's Width is set to 20 and test the flag before you set it to 20 again. Or you just test the current Width before you change it in any mouse triggered event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM