WPF Popup事件处理 - 如何在Popup打开时触发

时间:2010-09-08 13:41:38

标签: wpf popup triggers

我创建了一个WPF Popup,其中包含一个带边框的网格。 每次弹出窗口打开时,都会有一些与边框关联的动画。

目前代码是这样的

<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>

根据代码,边框首次显示动画,弹出窗口打开。 每次弹出窗口打开时,我需要做些什么更改才能触发边框动画?

5 个答案:

答案 0 :(得分:7)

根据这里给出的建议和现在的一点点(我在一年前问过这个:)),我可以找出解决方案。

<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;
    }

虽然我只能在这里设置Popup而不是Border的动画,但它几乎可以给出相同的结果。

答案 1 :(得分:1)

我不确定弹出窗口是否会在打开时获得焦点,但如果有,则可以使用GotFocus事件。或者,您可以尝试在isOpen属性上使用datatrigger。我认为你必须把它放在一种风格而不是内联。

答案 2 :(得分:0)

尝试将事件触发器更改为

<EventTrigger RoutedEvent="Popup.Opened">

答案 3 :(得分: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

答案 4 :(得分: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));

其中,RootSourcePropertyDependecyProperty的私有字段PresentationSource。在创建HwndSource并设置RootVisual时使用它的属性。因此,您只需使用RootSourceProperty的属性更改回调:

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

    }

这很好,因为您可以在所有应用程序和所有HwndSource(PopupWindow或自定义控件中使用它,您正在使用HwndSource