单击单元格时打开Popup延迟

时间:2014-11-20 20:04:45

标签: wpf popup wpfdatagrid

我想在选择列的任何单元格并且光标停留时间超过2秒时始终显示延迟2秒的弹出窗口。我可以用计时器和事件处理程序来实现它,但我想,我也可以通过故事板实现这一点。我试着这样做:

<Window x:Class="Wpfpopupstoryboard.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

<Window.Resources>
    <Storyboard x:Key="ShowPopup">
        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
            <DiscreteBooleanKeyFrame KeyTime="00:00:02.0" Value="True" />
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>

    <Storyboard x:Key="HidePopup" Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
        <BooleanAnimationUsingKeyFrames>
            <DiscreteBooleanKeyFrame KeyTime="00:00:00.1" Value="False" />
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <DataGrid Name="MyGrid" xmlns:sys="clr-namespace:System;assembly=mscorlib" IsReadOnly="True">
        <DataGrid.Resources>
            <Style TargetType="DataGridCell">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGridCell">
                            <StackPanel>
                                <Border x:Name="border"
                            BorderThickness="2"
                            BorderBrush="Silver">
                                    <ContentPresenter Name="MyContentPresenter" Content="{Binding}"/>

                                </Border>
                                <Popup x:Name="LockPopup" PlacementTarget="{Binding ElementName=MyContentPresenter}" Placement="Bottom"  DataContext="{Binding}">
                                    <TextBlock Text="This is a popup" Background="White" Foreground="Black" />
                                </Popup>
                            </StackPanel>

                            <ControlTemplate.Triggers>
                                <EventTrigger RoutedEvent="StackPanel.MouseLeftButtonDown">
                                    <BeginStoryboard Storyboard="{StaticResource ShowPopup}"/>
                                </EventTrigger>
                                <EventTrigger RoutedEvent="StackPanel.MouseLeave">
                                    <BeginStoryboard Storyboard="{StaticResource HidePopup}"/>
                                </EventTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding}" Header="column" />
        </DataGrid.Columns>
        <sys:String>item 1</sys:String>
        <sys:String>item 2</sys:String>
        <sys:String>item 3</sys:String>
        <sys:String>item 4</sys:String>
    </DataGrid>
</Grid>

有什么问题?有人可以帮帮我吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

使用RemoveStoryboard操作,您只需要1个Storyboard(显示弹出窗口)。此处触发故事板的正确事件是Selected,而不是StackPanel.MouseLeftButtonDown

<ControlTemplate.Triggers>
   <EventTrigger RoutedEvent="Selected">
      <BeginStoryboard Storyboard="{StaticResource ShowPopup}" Name="bg"/>
   </EventTrigger>
   <EventTrigger RoutedEvent="MouseEnter">
      <BeginStoryboard Storyboard="{StaticResource ShowPopup}" Name="bg2"/>
   </EventTrigger>
   <EventTrigger RoutedEvent="MouseLeave">
      <RemoveStoryboard BeginStoryboardName="bg"/>
   </EventTrigger>
</ControlTemplate.Triggers>

您可以删除HidePopup故事板,因为我们不需要上面的代码。

实际上你也可以使用StackPanel.PreviewMouseLeftButtonDown,以某种方式抑制StackPanel.MouseLeftButtonDown(从内部元素冒泡)。然而,它只是解释了为什么它一开始没有工作。使用Selected事件是最佳选择。

答案 1 :(得分:1)

MouseLeftButtonDown事件有Direct路由策略(请参阅UIElement.MouseLeftButtonDown Event (msdn))。

因此它不会冒泡到您的ContentTemplate

您需要直接在StackPanel设置事件触发器。