C# 使用dependency属性在n秒后隐藏元素的可见性
我的目标:我有一个C# 使用dependency属性在n秒后隐藏元素的可见性,c#,wpf,xaml,c#-4.0,attached-properties,C#,Wpf,Xaml,C# 4.0,Attached Properties,我的目标:我有一个按钮和一个图像图像将被隐藏,一旦用户将鼠标悬停在按钮上,则应显示图像。在用户将鼠标放在图像或按钮上之前,它应该是可见的。它应该在用户离开鼠标点6秒后隐藏图像(从按钮或图像)。鼠标在6秒前再次悬停并离开应重新启动计时器 我尝试的我已经有了一个可行的解决方案,使用AttachedProperty,但这并不有效。我感觉到由于这里的静态导致内存泄漏 public class MouseHoverBehavior { public static readonly Dependen
按钮
和一个图像
<默认情况下,代码>图像将被隐藏
,一旦用户将鼠标悬停在按钮上
,则应显示图像
。在用户将鼠标放在图像
或按钮
上之前,它应该是可见的。它应该在用户离开鼠标点6秒后隐藏图像(从按钮或图像)。鼠标在6秒前再次悬停并离开应重新启动计时器
我尝试的我已经有了一个可行的解决方案,使用AttachedProperty
,但这并不有效。我感觉到由于这里的静态
导致内存泄漏
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中:
有没有人有更好的办法来有效地做到这一点
谢谢。正如Chris W.所暗示的,最好的做法是使用
情节提要s和EventTrigger
s。这正是他们设计的场景。下面是它如何与您的示例一起工作(我将图像更改为矩形,以便可以轻松地进行测试):
你也可以让图像在5秒后开始淡出,在6秒后完全淡出,等等。我知道这看起来像是很多标记,但它非常灵活,避免了很多编码逻辑方面的麻烦,如果你想做更复杂的事情的话。(事实上,如果您想要更复杂的东西,无论如何都必须使用情节提要
,并且在代码中执行它们并不比在XAML中更漂亮)
但是,如果出于某种原因您不想使用故事板动画,那么您所做的对于特定场景来说似乎也很好。如果您担心内存泄漏(我不知道这些XAML元素在应用程序的生命周期中会被创建和销毁多少次,但除非它非常严重,否则我不会担心这一点;当FrameworkElement
卸载时,即使FEs本身没有获得GC,最重要的资源也会被释放),您可以在OnElementChanged
中订阅那些元素的卸载的
事件,并在处理这些事件时从Element\u MouseEnter
和Element\u MouseLeave
处理程序中取消订阅它们。您是否打算在codebehind中执行此操作?我可以向您展示如何使用故事板,但我更熟悉纯xaml的使用方法。@Chris。好的。如果你能以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>
<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>