2010-09-08 84 views
4

我创建了一个包含具有边框的网格的WPF弹出窗口。 有一些动画与我想要在每次Popup打开时触发的边框相关联。WPF弹出式事件处理 - 如何在弹出窗口打开时触发

目前的代码是这样的

<Popup x:Name="myPopUp" > 
    <Border x:Name="myBorder" > 
    <Border.Triggers> 
       <EventTrigger RoutedEvent="Popup.Loaded"> 
         <BeginStoryboard> 
          <Storyboard> 
           <DoubleAnimation 
            Storyboard.TargetName="myBorder" 
            Storyboard.TargetProperty="Height" 
            From="10" To="255" Duration="0:0:0.20" />      
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger> 
    </Border.Triggers> 
    <Grid /> 
    </Border> 
</Popup> 

按照代码中的边框显示了首次弹出打开动画。 每次Popup打开时,我需要做些什么来触发边界动画?

回答

6

按照建议在这里给出一个实现这一目标有点过期了(我问了一年回来:)),我可以找出解决方案。

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" > 
<Window.Resources> 
    <Style x:Key="popupStyle" TargetType="{x:Type Popup}" > 
     <Style.Triggers> 
      <Trigger Property="IsOpen" Value="True"> 
       <Trigger.EnterActions> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation 
           Storyboard.TargetProperty="Height" 
           From="10" To="255" Duration="0:0:0.20" /> 
         </Storyboard> 
        </BeginStoryboard> 
       </Trigger.EnterActions> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <Button Width="100" Height="100" Click="Button_Click"></Button> 
    <Popup Name="popUp" Width="100" Height="100" Style="{StaticResource popupStyle}" > 
     <Border x:Name="myBorder" Background="Blue"/> 
    </Popup> 
</Grid> 

和示例代码背后触发弹出..

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     popUp.PlacementTarget = (Button)sender; 
     popUp.IsOpen = true; 
    } 

虽然我只能动画弹出,而不是这里的边界,它几乎给出了相同的结果。

1

我不确定弹出窗口在打开时是否获得焦点,但是如果它确实可以使用GotFocus事件。或者,您可以尝试在IsOpen属性上使用数据触发器。我认为你必须把它放在风格上,而不是内联。

+0

它没有得到重点。请从您的答案中删除这个,我会upvote。 – David 2016-09-19 08:55:42

0

试着改变你的事件触发

<EventTrigger RoutedEvent="Popup.Opened">

+0

Popup.Opened不是路由事件,这是正常事件。 – mdm20 2010-09-08 15:18:03

+0

我的第一个直觉就是尝试这个,但是因为mdm20提到Opened不是路由事件,所以不能在EventTrigger中使用它。但是我正在寻找一个像这个代码一样简单的解决方案。 – 2010-09-09 15:31:08

+0

为什么这个错误的答案有3个upvotes? – Sinatr 2016-03-18 08:51:14

0

您可以通过听IsOpen依赖属性像

public MainWindow() 
    { 
     InitializeComponent(); 

     //// Listening to the IsOpen dependency property of the Popup. 
     this.SetBinding(PopupIsOpenProperty, new Binding() { Source = this.popupContainer, Path = new PropertyPath("IsOpen") }); 
    } 

    /// <summary> 
    /// Gets or sets a value indicating whether [popup is open]. 
    /// </summary> 
    /// <value><c>true</c> if [popup is open]; otherwise, <c>false</c>.</value> 
    public bool PopupIsOpen 
    { 
     get { return (bool)GetValue(PopupIsOpenProperty); } 
     set { SetValue(PopupIsOpenProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for PopupIsOpen. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty PopupIsOpenProperty = 
     DependencyProperty.Register("PopupIsOpen", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, 
      (dependencyObject, e) => 
      { 
       var mainWindow = (MainWindow)dependencyObject; 

       if (mainWindow != null && 
        (bool)e.NewValue == true) 
       { 
        //// Raise your event here... like 
        //// mainWindow.RaisePopupOpened(); 
        System.Diagnostics.Debug.WriteLine("Popup Open Triggered"); 
       } 
      })); 

    private void button_MouseLeave(object sender, MouseEventArgs e) 
    { 
     this.popupContainer.IsOpen = false; 
    } 

    private void button_MouseMove(object sender, MouseEventArgs e) 
    { 
     //// Setting the popup position 
     var p = e.GetPosition(sender as UIElement); 
     this.popupContainer.HorizontalOffset = p.X; 
     this.popupContainer.VerticalOffset = p.Y; 

     //// Enabling popup when it is hover on the button 
     this.popupContainer.IsOpen = true; 
    } 


<!-- XAML Starts here--> 
<Grid> 
    <Button x:Name="button1" Content="This is a sample text" MouseMove="button_MouseMove" MouseLeave="button_MouseLeave" Width="100" Height="25" /> 
    <Popup x:Name="popupContainer" IsHitTestVisible="False" > 
     <Grid Background="White"> 
      <TextBlock Text="{Binding Content, ElementName=button}" /> 
     </Grid> 
    </Popup> 
</Grid> 

HTH

+0

此解决方案适用于我。然而,我觉得这种方式可以让你在一段时间内完成任务。我想知道是否会有单行(或只有更小的XAML)代码来解决这个问题。在cs代码中这样做意味着我将不得不将事件处理程序代码(本例中为边框动画)移动到cs。 – 2010-09-09 15:28:02

+0

如果IsOpened已被绑定,则不起作用。 – David 2016-09-19 09:10:02

+0

如果你在后面的代码中执行此操作,还必须注册到弹出窗口中的Opened事件:) – Oyiwai 2017-07-17 08:45:13

0

在App.xaml.cs或在另一个起点类实例,你需要添加:

var field = typeof(PresentationSource).GetField("RootSourceProperty", BindingFlags.NonPublic | BindingFlags.Static); 
     var property = (DependencyProperty)field.GetValue(null); 
     property.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(property.DefaultMetadata.DefaultValue, OnHwndSourceChanged)); 

其中,RootSourceProperty是私人领域的PresentationSourceDependecyProperty。在创建HwndSource并设置RootVisual时使用它的属性。所以,你只需要使用属性改回叫的RootSourceProperty

private static void OnHwndSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 

    } 

这是很好的,因为你可以在你的所有应用程序以及所有HwndSource(PopupWindow或自定义的控制,你在哪里使用HwndSource)使用

相关问题