开发者

WPF Popup event handling - How to get triggered when Popup opens

I created a WPF Popup which contains a grid with border. There is some animation associated with the border which I want to be triggered every time the Popup opens.

Currently the code is like this

<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" />                      
     开发者_StackOverflow                       </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
     </Border.Triggers>
     <Grid />
   </Border>
</Popup>

As per the code the border shows up the animation for the first time the popup opens. What change do I need to make to trigger the border animation every time the Popup opens?


As per suggestions given here and a little bit expireince now (I asked this a year back :) ), I could figure out the solution.

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

and a sample code behind to trigger the popup..

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

Although I can only animate the Popup and not the Border here, it pretty much gives the same result.


I'm not sure if the popup gets focus when it opens, but you could use the GotFocus event if it does. Alternatively, you could try using a datatrigger on the is IsOpen property. I think you'd have to put that in a style though instead of inline.


You can achieve this by listening to the IsOpen dependency property like

    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


In App.xaml.cs or in another starting class instance you need add:

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

Where, RootSourceProperty is private field DependecyProperty of PresentationSource. Its property use when HwndSource is created and set RootVisual. So you need just use property changed call back of RootSourceProperty:

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

    }

This is nice because, you can use it in your all Application and for all HwndSource (Popup, Window or Custom controls, where you are using HwndSource)


try changing your event trigger to

<EventTrigger RoutedEvent="Popup.Opened">

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜