Я просто хочу открыть WPF Popup с задержкой, вроде как ToolTip.Как открыть всплывающее окно WPF с задержкой?
Как я могу это достичь?
И, кстати, Popup.PopupAnimation = PopupAnimation.Fade ... быстро исчезает. Я хочу, по крайней мере, полсекунды.
Я просто хочу открыть WPF Popup с задержкой, вроде как ToolTip.Как открыть всплывающее окно WPF с задержкой?
Как я могу это достичь?
И, кстати, Popup.PopupAnimation = PopupAnimation.Fade ... быстро исчезает. Я хочу, по крайней мере, полсекунды.
Прежде всего ... кредит на этот ответ отправляется Eric Burke. Он answered этот самый вопрос отправлен в группу WPF Disciples. Я подумал, что было бы полезно поставить этот ответ на StackOverflow тоже.
В принципе, вам необходимо анимировать свойство IsOpen всплывающего окна с помощью DiscreteBooleanKeyFrame.
Проверьте следующую 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>
Пожалуйста, обратите внимание, что я немного ... изменил его оригинальное решение, чтобы вызвать IsOpen по сравнению с проверкой CheckBox, как и у него. Все в попытке заставить Popup вести себя немного как ToolTip.
Ответ на вопросник cplotts хороший, но может не применяться в вашем случае, потому что он оставляет анимацию прикрепленной к свойству IsOpen, эффективно блокируя ее на месте и препятствуя ее изменению с помощью настройки свойств, привязки и других способов , Это может затруднить использование вашего кода в зависимости от того, как вы его используете.
Если это так, то я хотел бы перейти на начало DispatcherTimer, когда вы хотите, чтобы открыть всплывающее окно, после некоторой задержки, например:
_popupTimer = new DispatcherTimer(DispatcherPriority.Normal);
_popupTimer.Interval = TimeSpan.FromMilliseconds(100);
_popupTimer.Tick += (obj, e) =>
{
_popup.IsOpen = true;
};
_popupTimer.Start();
Для всплывающей подсказки типа поведения это может быть сделано на MouseEnter , Если вы хотите, чтобы закрыть всплывающее отверстие для какой-либо причине (например, если мышь покидает элемент управления до появления всплывающего окна), просто:
_popupTimer.Stop();
Update
Как cplotts obseved в комментарии, вы также захочет установить _popup.IsOpen = false
в некоторых ситуациях в событии MouseLeave, в зависимости от вашей логики для обработки событий ввода/вывода мыши между вашим элементом управления и всплывающим окном. Имейте в виду, что вы обычно не хотите слепо устанавливать IsOpen=false
на каждое событие MouseLeave, потому что он может это сделать, когда всплывающее окно появляется над ним. В некоторых ситуациях это приведет к появлению мерцающего всплывающего окна. Поэтому вам понадобится какая-то логика.
System.Windows.Controls.ToolTip tp = new System.Windows.Controls.ToolTip();
System.Windows.Threading.DispatcherTimer tooltipTimer =
new System.Windows.Threading.DispatcherTimer
(
System.Windows.Threading.DispatcherPriority.Normal
);
private void TooltipInvalidCharacter()
{
tp.Content =
"A flie name cannot contain any of the following character :" +
"\n" + "\t" + "\\/: * ? \" < > |";
tooltipTimer.Interval = TimeSpan.FromSeconds(5);
tooltipTimer.Tick += new EventHandler(tooltipTimer_Tick);
tp.IsOpen = true;
tooltipTimer.Start();
}
void tooltipTimer_Tick(object sender, EventArgs e)
{
tp.IsOpen = false;
tooltipTimer.Stop();
}
Хотя ваш ответ вообще не отвечает на вопрос, он вызывает тот факт, что вы часто хотите скрыть подсказку инструмента через некоторое время. Что-то иметь в виду. – cplotts
Вы можете расширить XAML для этого решения, чтобы всплывающее окно оставалось открытым, пока мышь над ним, а затем автоматически исчезает.
я изменил образец следующим образом:
Эта версия превращает синюю попку, когда мышь над ней, чтобы вы могли видеть последовательность событий с помощью Kaxaml.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="TooltipPopup">
<Grid>
<CheckBox
x:Name="cb"
Width="100"
Height="40"
Content="Hover Over Me"/>
<Popup
x:Name="popup"
Placement="Bottom"
PlacementTarget="{Binding ElementName=cb}">
<Border x:Name="border" Width="400" Height="400" Background="Red"/>
</Popup>
</Grid>
<DataTemplate.Resources>
<Storyboard x:Key="ClosePopup">
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="popup"
Storyboard.TargetProperty="IsOpen"
FillBehavior="Stop">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<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"/>
<BeginStoryboard x:Name="bxb" Storyboard="{StaticResource ClosePopup}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger SourceName="popup" Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="Blue"/>
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="bxb"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ClosePopup}"/>
<RemoveStoryboard BeginStoryboardName="bxb"/>
</Trigger.ExitActions>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Page>
Вы можете создать стиль для применения к Всплывающие следующим образом:
<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>
Затем, когда вы хотите использовать его, вы бы писать разметки похожее на это (обратите внимание, связывание для 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>
Хороший вопрос ... и хорошая идея. Возможно, вы захотите также очистить значение IsOpen в MouseLeave в приведенном выше решении. – cplotts
Да, вы, вероятно, захотите это сделать, но внимательно. Я уточню свой ответ, чтобы объяснить, что я имею в виду. –
Рэй, огромное спасибо! Это была именно та функциональность, в которой я нуждался. – Stewbob