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

发布于 2024-09-18 14:16:15 字数 947 浏览 6 评论 0原文

我创建了一个 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>

根据代码,边框在弹出窗口第一次打开时显示动画。 每次弹出窗口打开时,我需要进行哪些更改才能触发边框动画?

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" />                      
                            </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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

GRAY°灰色天空 2024-09-25 14:16:16

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

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.

清音悠歌 2024-09-25 14:16:16

您可以通过监听 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)来实现此目的

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

維他命╮ 2024-09-25 14:16:16

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

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

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

    }

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

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)

萌梦深 2024-09-25 14:16:16

尝试将事件触发器更改为

try changing your event trigger to

<EventTrigger RoutedEvent="Popup.Opened">

尐籹人 2024-09-25 14:16:15

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

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

虽然我只能为弹出窗口设置动画,而不能为边框设置动画,但它几乎给出了相同的结果。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文