2015-06-04 29 views
9

Tôi có WPF behavior về kiểm soát cụ thể. Khi tôi đóng cửa sổ giữ điều khiển, chức năng OnDetaching không được gọi.Chức năng OnDetaching của hành vi không được gọi là

Hành vi tiếp tục tồn tại (vì các sự kiện được đăng ký), mặc dù cửa sổ không còn tồn tại nữa (rò rỉ bộ nhớ).

Tại sao chức năng OnDetaching không kích hoạt **** và làm cách nào tôi có thể giải quyết?

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; 
} 

Trả lời

9

Các OnAttached được gọi khi XAML phân tích cú pháp phân tích cú pháp XAML và tạo ra một thể hiện của một hành vi mà thêm vào BehaviorCollection của sự kiểm soát mục tiêu đó được tiếp xúc như bất động sản DependencyAttached.

Tuy nhiên, nếu xem được xử lý, bộ sưu tập (Bộ sưu tập hành vi) đã được xử lý, nó sẽ không bao giờ kích hoạt phương pháp OnDetaching.

Nếu hành vi không dọn dẹp đúng cách, GC sẽ không thu thập và cũng sẽ giữ Hành vi sưu tập và các hành vi khác trong bộ sưu tập đó. Các hành vi được thiết kế để mở rộng AssociatedObject, miễn là bạn đang đăng ký các sự kiện AssociatedObject, nó sẽ bị phạt vì AssociatedObject (publisher) sẽ chết và hành vi của bạn sẽ được thu thập bởi bộ gom rác.

A good source.


Một cách khác là để xử lý các "Đóng" sự kiện (khi người dùng nhấp phía trên bên phải nút 'X') của cửa sổ, và OnDetaching đó.

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

Sau đó, kết hợp xử lý trong Xem constructor:

MyWindow() 
{ 
    // Set up ViewModel, assign to DataContext etc. 
    Closing += viewModel.OnWindowClosing; 
} 

Và thêm xử lý đến ViewModel:

public void OnWindowClosing(object sender, CancelEventArgs e) 
{ 
    // Cancel, OnDetaching, etc 
} 
+0

Nếu câu trả lời này giúp vui lòng upvote để bạn thực sự sẽ giành được một huy hiệu 'Nice answer' :) –

2

Hãy thử để đăng ký sự kiện AssociatedObject.Unloaded và bên trong eventHander hủy đăng ký tất cả các sự kiện chuột. Hành vi OnDetaching() func. không phải lúc nào cũng được gọi vào "thời gian".

+0

Lưu ý rằng nếu mục được giới thiệu lại cho cây thị giác, hành vi của bạn sẽ không hoạt động nữa; – Rune

Các vấn đề liên quan