如何以延迟打开WPF弹出窗口?

cpl*_*tts 13 wpf popup delay wpf-controls

我只是想延迟打开WPF Popup,有点像ToolTip.

我怎样才能做到这一点?

顺便说一下,Popup.PopupAnimation = PopupAnimation.Fade ......过快地消失了.我想在那里至少半秒钟.

Jul*_*uez 14

您可以通过以下方式创建要应用于Popup的样式:

<Style x:Key="TooltipPopupStyle" TargetType="Popup">
    <Style.Triggers>
        <DataTrigger Binding="{Binding PlacementTarget.IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="OpenPopupStoryBoard" >
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:0.25" Value="True"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <BeginStoryboard x:Name="ClosePopupStoryBoard">
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:1" Value="False"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>

        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <PauseStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <ResumeStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)

然后,只要你想使用它,就可以编写与此类似的标记(注意PlacementTarget的绑定):

<TextBlock x:Name="TargetControl" Text="Hover over me!" />
<Popup PlacementTarget="{Binding ElementName=TargetControl}" Style="{StaticResource TooltipPopupStyle}">
    <Border BorderBrush="Red" BorderThickness="1" Background="White">
        <TextBlock Text="This is a Popup behaving somewhat like the tooltip!" Margin="10" />
    </Border>
</Popup>
Run Code Online (Sandbox Code Playgroud)


Ray*_*rns 10

答案cplotts粘贴是好的,但可能不适用于您的情况,因为它将动画附加到IsOpen属性,有效地将其锁定到位并防止通过直接属性设置,绑定和其他方式更改它.这可能会使您难以使用代码,具体取决于您使用它的方式.

如果是这种情况,当你想在一段时间后打开弹出窗口时,我会切换到启动DispatcherTimer,如下所示:

_popupTimer = new DispatcherTimer(DispatcherPriority.Normal);
_popupTimer.Interval = TimeSpan.FromMilliseconds(100);
_popupTimer.Tick += (obj, e) =>
{
  _popup.IsOpen = true;
};
_popupTimer.Start();
Run Code Online (Sandbox Code Playgroud)

对于类似ToolTip的行为,可以在MouseEnter上完成.如果由于某种原因想要取消弹出窗口(例如,如果鼠标在弹出窗口出现之前离开控件),只需:

_popupTimer.Stop();
Run Code Online (Sandbox Code Playgroud)

更新

正如在注释中观察到cplotts一样,您还需要_popup.IsOpen = false在MouseLeave事件中设置某些情况,具体取决于您在控件和弹出窗口之间处理鼠标进入/退出事件的逻辑.请注意,您通常不希望盲目地设置IsOpen=false每个MouseLeave事件,因为当弹出窗口出现在它上面时它可能会这样做.在某些情况下,这会导致闪烁的弹出窗口.所以你需要一些逻辑.


cpl*_*tts 8

首先......这个答案归功于Eric Burke.他回答了WPF门徒组中发布的这个问题.我认为将这个答案放在StackOverflow上会很有用.

基本上,您需要使用DiscreteBooleanKeyFrame为Popup的IsOpen属性设置动画.

查看以下xaml(可以轻松粘贴到Kaxaml或其他松散的xaml编辑实用程序中):

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
    <ContentPresenter>
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox
                        x:Name="cb"
                        Width="100"
                        Height="40"
                        Content="Hover Over Me"
                    />
                    <Popup
                        x:Name="popup"
                        Placement="Bottom"
                        PlacementTarget="{Binding ElementName=cb}"
                    >
                        <Border Width="400" Height="400" Background="Red"/>
                    </Popup>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger SourceName="cb" Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="bsb">
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames
                                        Storyboard.TargetName="popup"
                                        Storyboard.TargetProperty="IsOpen"
                                        FillBehavior="HoldEnd"
                                    >
                                        <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
                                     </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <StopStoryboard BeginStoryboardName="bsb"/>
                        </Trigger.ExitActions>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>
</Page>
Run Code Online (Sandbox Code Playgroud)

请注意,我稍微修改了他的原始解决方案...在鼠标上触发IsOpen而不是检查CheckBox.所有人都试图让Popup表现得像ToolTip.