Silverlight コントロールでいくつかのブレンド動作とトリガーを使用しています。コントロールが使用されなくなったとき (つまり、ビジュアル ツリーから削除されたとき) に、動作またはトリガーに対して OnDetaching() が自動的にデタッチまたは確実に呼び出されるようにするメカニズムがあるかどうか疑問に思っています。
私の問題は、動作の 1 つが原因で、コントロールにマネージ メモリ リークがあることです。この動作は、OnAttached() オーバーライドで存続期間の長いオブジェクトのイベントにサブスクライブし、OnDetaching() オーバーライドでそのイベントからサブスクライブを解除して、ガベージ コレクションの候補にできるようにする必要があります。ただし、ビジュアルツリーからコントロールを削除すると、OnDetaching() が呼び出されることはないようです...それを実現できる唯一の方法は、コントロールを削除する前に問題のある動作を明示的にデタッチすることであり、適切にガベージコレクションされます.
現時点で私の唯一の解決策は、ガベージ コレクションの問題を引き起こす既知の動作を通過して切り離すことができるコントロールのコード ビハインドにパブリック メソッドを作成することでした。パネルからコントロールを削除する前にこれを呼び出すかどうかは、クライアント コード次第です。私はこのアプローチがあまり好きではないので、見落としている自動化された方法またはより良い提案を探しています。
public void DetachBehaviors()
{
foreach (var behavior in Interaction.GetBehaviors(this.LayoutRoot))
{
behavior.Detach();
}
//continue detaching all known problematic behaviors on the control....
}