使用依赖属性在n秒后隐藏元素的可见性
我的目标:我有一个Button
和一个Image
。 Image
默认为Hidden
,一旦用户将鼠标悬停在Button
上,应显示Image
。它应该是可见的,直到用户将鼠标悬停在Image
或Button
上。它应该在用户离开鼠标点6秒后(隐藏按钮或图像)隐藏图像。鼠标在6秒前悬停,离开时应重新启动计时器。使用依赖属性在n秒后隐藏元素的可见性
我试过我已经有一个可行的解决方案,使用AttachedProperty
但这不是有效的。我感觉这里会有内存泄漏,因为这里有static
。
public class MouseHoverBehavior
{
public static readonly DependencyProperty ElementProperty = DependencyProperty.RegisterAttached(
"Element", typeof(UIElement), typeof(MouseHoverBehavior), new UIPropertyMetadata(OnElementChanged));
private static UIElement target;
static MouseHoverBehavior()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(6);
timer.Tick += Timer_Tick;
}
private static void OnElementChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var element = (sender as Button);
target = (UIElement)e.NewValue;
target.Visibility = Visibility.Hidden;
element.MouseEnter += Element_MouseEnter;
target.MouseEnter += Element_MouseEnter;
element.MouseLeave += Element_MouseLeave;
target.MouseLeave += Element_MouseLeave;
}
private static DispatcherTimer timer;
private static void Element_MouseLeave(object sender, MouseEventArgs e)
{
timer.Start();
}
private static void Timer_Tick(object sender, EventArgs e)
{
target.Visibility = Visibility.Hidden;
}
private static void Element_MouseEnter(object sender, MouseEventArgs e)
{
timer.Stop();
target.Visibility = Visibility.Visible;
}
public static void SetElement(DependencyObject element, UIElement value)
{
element.SetValue(ElementProperty, value);
}
public static string GetElement(DependencyObject element)
{
return (string)element.GetValue(ElementProperty);
}
}
在XAML:
<StackPanel>
<Image Source="steve.jpg" Width="200" x:Name="image"/>
<Button Width="200" Height="100" Margin="20" local:MouseHoverBehavior.Element="{Binding ElementName=image}"/>
</StackPanel>
没有人在有效的方式这样做的更好的主意。
谢谢。
正如Chris W.所暗示的那样,最佳做法是使用Storyboard
s和EventTrigger
s。这正是他们设计的场景。下面是它如何与你的榜样工作(我改变了图像的矩形,所以我可以很容易地测试它):
<StackPanel>
<StackPanel.Triggers>
<EventTrigger SourceName="_button" RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="_button" RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:00:06"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="image" RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="image" RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard Duration="1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:00:06"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<Button x:Name="_button"
Width="200" Height="100" Margin="20" />
<Rectangle Visibility="Collapsed"
Width="200"
Height="200"
Fill="Yellow"
x:Name="image"/>
</StackPanel>
你也可以有6等后的图像淡出开始5秒后,完全我知道它看起来像很多标记,但它非常灵活,并且避免了许多编码逻辑头痛,如果你想做更复杂的事情,你会经历的。 (事实上,如果你想要更复杂的东西,那么你必须使用Storyboard
,并且在代码中执行操作并不比XAML更漂亮)。
但是,如果您不想使用故事板动画出于某种原因,那么对于您的特定场景,您所做的事情似乎也很好。如果您担心内存泄漏(我不知道这些XAML元素在应用程序的整个生命周期中会创建和销毁多少次,但除非有很多我不担心这个;最重要的是资源在FrameworkElement
被卸载时释放,即使FE本身没有得到GC'd),您可以在您的OnElementChanged
订阅这些元素的“Unloaded
”事件,并在处理这些事件时从您的Element_MouseEnter
和Element_MouseLeave
处理程序取消订阅它们。
太好了。感谢您的回答。我可以有故事板。让我试试这个。 – Gopichandar
你是否在代码隐藏方面做了设置?我可以告诉你如何与故事板,但纯XAML是更熟悉我如何做到这一点。 –
@Chris。 。是的,请。如果你只能以xaml的方式给我,这将是非常好的。 – Gopichandar