Hãy tập trung vào ProjectAdded
sự kiện (mặc dù vấn đề được mô tả là giống hệt nhau cho phần còn lại của các sự kiện).
Mẫu mã bạn đã hiển thị các nỗ lực để đăng ký trình xử lý SolutionEvents_ProjectAdded
cho sự kiện ProjectAdded
. Tuy nhiên, đối tượng SolutionEvents
phơi bày sự kiện, có phạm vi thời gian giới hạn cho việc đóng gói phương thức gói của nó (bạn chưa hiển thị chữ ký của nó - hãy gọi nó là Connect
). Sau khi kiểm soát dòng chảy đã rời khỏi phạm vi đó, đối tượng địa phương đã được thu gom rác thải, vì vậy sự kiện của nó không bao giờ được gọi là:
đang bị hỏng:
public class Connector
{
public void Connect()
{
((Events2)dte.Events).SolutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback is dead
}
}
Để khắc phục điều đó, bạn cần phải gán các SolutionEvents
đối tượng cho một số biến, có thời gian tồn tại trên bộ xử lý SolutionEvents_ProjectAdded
- ví dụ trên toàn bộ lớp học. Trong ví dụ dưới đây, phạm vi mở rộng trên toàn bộ loại (chúng ta hãy gọi nó Connector
), và đảm bảo rằng xử lý có thể truy cập trong thời gian tồn tại của loại hình đó:
Cố định mã:
public class Connector
{
SolutionEvents _solutionEvents;
public void Connect()
{
_solutionEvents = ((Events2)dte.Events).SolutionEvents;
_solutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback works
}
}
Để được chính xác hơn, kiểm tra thông tin này MSDN - Scoping Variables Appropriately in Event Handlers:
một sai lầm phổ biến trong các xử lý sự kiện lập trình được kết nối xử lý sự kiện đến một đối tượng mà đã được tuyên bố w ith phạm vi quá giới hạn cho mục đích xử lý sự kiện. Các đối tượng phải có một cuộc sống mà không chỉ vượt qua chức năng kết nối gọi lại phương pháp như một xử lý sự kiện của đối tượng, mà còn trên các phương pháp gọi lại chính nó, nơi sự kiện này thực sự được xử lý.Nếu không, nếu đối tượng nằm ngoài phạm vi và không còn được xác định trong phương thức gọi lại , phương thức gọi lại không được gọi và sự kiện không được xử lý như mong muốn.
'_hSolutionEvents' trong' Initialize() 'là gì? –
Bạn nói đúng, đã cập nhật mã! Đã có một suy nghĩ về '_hSolutionEvents' đó là cần thiết cho' UnadviseSolutionEvents' và thêm mã mới, quá. Thật đáng tiếc là không có nhiều thông tin về việc tạo plugin cho DevTool tốt nhất ... – FooBarTheLittle