我在特定控件上有WPF behavior。当我关闭保存控件的窗口时,不调用OnDetaching函数。

尽管该窗口不再存在(内存泄漏),但该行为继续存在(由于它已注册的事件)。

为什么OnDetaching函数不触发,我该如何解决?

protected override void OnAttached()
{
     base.OnAttached();

     this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_PlotAreaMouseLeftButtonDown;
     this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_PlotAreaMouseLeftButtonUp;
     this.AssociatedObject.MouseMove += AssociatedObject_PlotAreaMouseMove;
}

protected override void OnDetaching()
{
     base.OnDetaching();

     this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_PlotAreaMouseLeftButtonDown;
     this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_PlotAreaMouseLeftButtonUp;
     this.AssociatedObject.MouseMove -= AssociatedObject_PlotAreaMouseMove;
}

最佳答案

当XAML解析器解析XAML并创建一个行为的实例时,就会调用OnAttached,该行为的实例将添加到作为DependencyAttached属性公开的目标控件的BehaviorCollection中。

但是,如果处置了 View ,则处置了集合(Behavior集合),它将永远不会触发OnDetaching方法

如果未正确清除该行为,则GC将不会收集该行为,并且还将保存BehaviorCollection和该集合中的其他行为。这些行为旨在扩展AssociatedObject,只要您订阅AssociatedObject事件,它的行为就很好,因为AssociatedObject(发布者)将死亡,并且您的行为将被垃圾收集器收集。

A good source

一种替代方法是处理窗口的“关闭”事件(当用户单击右上角的“X”按钮时),并使用OnDetaching那里。

 <i:Interaction.Triggers>
        <i:EventTrigger EventName="Closing">
            <cmd:EventToCommand Command="{Binding CloseCommand}" />
        </i:EventTrigger>
 </i:Interaction.Triggers>

然后在View构造函数中关联处理程序:
MyWindow()
{
    // Set up ViewModel, assign to DataContext etc.
    Closing += viewModel.OnWindowClosing;
}

并将处理程序添加到ViewModel中:
public void OnWindowClosing(object sender, CancelEventArgs e)
{
   // Cancel, OnDetaching, etc
}

关于c# - 行为的OnDetaching函数未调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30638292/

10-13 06:49