如果对象被释放,则阻止鼠标离开触发器
本文关键字:鼠标 离开 触发器 对象 释放 如果 | 更新日期: 2023-09-27 18:35:31
我有一个网格,当鼠标悬停在上面时,它会使其子元素之一栩栩如生(不透明度从 0 到 1),但该网格也可以处理(该网格是列表框的一部分,可以通过网格上的关闭按钮删除)。
当用户单击删除按钮时,它还会在下面启动 MouseLeave 事件,当然,由于它被释放,就无法再找到我的 DockStackPanel 控件了。如何解决此问题?
<Grid.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="DockStackPanel" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="DockStackPanel" Storyboard.TargetProperty="Opacity" To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
您是否尝试过在代码中创建动画。我在这里假设 DockStackPanel 控件是一个 StackPanel。
public MainWindow()
{
InitializeComponent();
MyGrid.MouseEnter += MyGrid_MouseEnter;
MyGrid.MouseLeave += MyGrid_MouseLeave;
}
void MyGrid_MouseLeave(object sender, MouseEventArgs e)
{
if (DockStackPanel != null)
{
var dur = new Duration(new TimeSpan(0, 0, 0, 0, 500));
var anim = new DoubleAnimation(0, dur);
DockStackPanel.BeginAnimation(StackPanel.OpacityProperty, anim);
}
}
void MyGrid_MouseEnter(object sender, MouseEventArgs e)
{
var dur = new Duration(new TimeSpan(0, 0, 0, 0, 500));
var anim = new DoubleAnimation(1, dur);
DockStackPanel.BeginAnimation(StackPanel.OpacityProperty, anim);
}
您可以
做的另一件事是为Grid
实现DataTrigger
,这将覆盖默认MouseLeave
,并在属性更改时MouseEnter
事件DisableTriggers
不执行任何操作。
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding DisableTriggers}" Value="True">
<Setter Property="Style" Value="{StaticResource GridStyleWithoutStoryboards}" />
</DataTrigger>
</Style.Triggers>
</Style>
当您不想使用AttachedBehaviors
时就是这种情况。否则,我建议在行为中处理故事板清理。这要容易得多:
void OnDisableTriggersPropertyChanged( object sender, EventArgs args )
{
// If IsDisposed property was changed and it is true now - cleanup triggers.
if ((bool)args.NewValue)
{
var grid = (Grid)sender;
// Ideally you can remove specific triggers.
// Clear all will work for simple cases.
grid.Triggers.Clear();
}
}
因此,总而言之,您必须使用依赖项属性添加附加行为DisableTriggers
该属性OnChanged
处理程序中执行清理操作。
如果您只想取消订阅特定活动:
foreach (var eventToUnsubscribe in grid.Triggers.OfType<EventTrigger>()
.Where(x => x.RoutedEvent == UIElement.MouseEnterEvent
|| x.RoutedEvent == UIElement.MouseLeaveEvent).ToList())
{
grid.Triggers.Remove(eventToUnsubscribe);
};