2014-11-20 56 views
1

我希望總是選擇列的任意單元格並且光標停留時間超過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> 

有什麼不對?有人能幫助我嗎?

謝謝!

回答

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

感謝King King,它工作得很好。 – MrScf 2014-11-20 21:07:48

1

MouseLeftButtonDown事件有一個Direct路由策略(請參閱UIElement.MouseLeftButtonDown Event (msdn))。

所以它不會冒泡到您的ContentTemplate

您需要直接在StackPanel上設置事件觸發器。