2009-07-01 33 views
11

Tôi có một ứng dụng .Net 3.5 C# Winforms. Nó không có GUI như vậy, chỉ là một NotifyIcon với một ContextMenu.Vấn đề với NotifyIcon không biến mất trên Winforms App

Tôi đã cố gắng để thiết lập các NotifyIcon để có thể nhìn thấy = false và vứt bỏ nó trong trường hợp Application_Exit, như sau:

 if (notifyIcon != null) 
     { 
      notifyIcon.Visible = false; 
      notifyIcon.Dispose(); 
     } 

Ứng dụng được vào mã bên trong dấu ngoặc, nhưng ném một ref rỗng ngoại lệ khi nó cố gắng đặt Visible = false.

Tôi đã đọc ở một vài nơi để đặt nó trong sự kiện đóng biểu mẫu, nhưng mã đó không bao giờ bị trúng (có thể vì tôi không có biểu mẫu hiển thị như vậy?).

Tôi có thể đặt mã này ở đâu để nó thực sự hoạt động? Nếu tôi không đặt nó vào, tôi nhận được biểu tượng kéo dài khó chịu trong khay cho đến khi bạn di chuyển chuột qua nó.

Chúc mừng.

EDIT

Chỉ cần một cái gì đó thêm tôi đã nhận thấy ...........

Tôi đang sử dụng ClickOnce trong ứng dụng ....... ..if Tôi chỉ cần thoát khỏi ứng dụng thông qua ContextMenu trên NotifyIcon, không có ngoại lệ nào được ghi lại.

Chỉ khi sự kiện Application_Exit là bắn sau khi Application đã kiểm tra một bản nâng cấp ở đây ..

private void CheckForUpdate() 
{ 
    EventLogger.Instance.LogEvent("Checking for Update"); 
    if (ApplicationDeployment.IsNetworkDeployed && ApplicationDeployment.CurrentDeployment.CheckForUpdate()) 
    { 
     EventLogger.Instance.LogEvent("Update available - updating"); 
     ApplicationDeployment.CurrentDeployment.Update(); 
     Application.Restart(); 
    } 
} 

Liệu sự giúp đỡ này?

Trả lời

3

Mã này làm việc cho tôi, nhưng tôi không biết làm thế nào bạn đang giữ ứng dụng của bạn còn sống, như vậy ... không có thêm ado:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

static class Program 
{ 
    static System.Threading.Timer test = 
     new System.Threading.Timer(Ticked, null, 5000, 0); 

    [STAThread] 
    static void Main(string[] args) 
    { 
     NotifyIcon ni = new NotifyIcon(); 
     ni.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); 
     ni.Visible = true; 

     Application.Run(); 
     ni.Visible = false; 
    } 

    static void Ticked(object o) { 
     Application.Exit(); 
    } 
} 
0

Đôi khi Application_Exit sự kiện có thể được nâng lên nhiều lần Chỉ cần đặt notifyIcon = null; vào cuối

if (notifyIcon != null) 
{ 
    notifyIcon.Visible = false; 
    notifyIcon.Dispose(); 
    notifyIcon = null; 
} 
+0

Trên thực tế, bây giờ mà tôi nghĩ về nó, tôi khuyên bạn nên chống lại sử dụng sự kiện này cho điều này bởi vì nó có thể có một vài Application.Run() loops đi trên các chủ đề khác nhau và tất cả chúng sẽ kích hoạt sự kiện Thoát có thể khiến biểu tượng của bạn biến mất sớm. –

+0

Hoàn toàn đồng ý với bạn! Tôi không muốn sử dụng sự kiện này trong các ứng dụng của tôi cho bất kỳ mục đích dọn sạch nào. Tuy nhiên, nó là câu trả lời đơn giản nhất cho câu hỏi "tại sao mã này ném một ngoại lệ". Theo ý tưởng của tôi làm thế nào để thiết kế mã này theo một cách khác, tôi có thể đề xuất để tạo ra một lớp bao bọc dùng một lần xung quanh notifyIcon, do đó, nó sẽ kiểm soát toàn bộ thời gian của notificationIcon. và sau đó viết bằng cách sử dụng (mới NotifyIconController()) {Application.Run()}; hoặc một cái gì đó như thế này –

3

Đây là những gì tôi đang làm trong WPF.

Tôi đang sử dụng kết hợp này với số Minimize to tray sample app của David Anson, cho phép bạn treo biểu tượng khay lên cửa sổ (bạn có thể mở nhiều cửa sổ).

Chỉ cần thêm mã này vào hàm tạo cho MinimizeToTrayInstance.

_window.Closed += (s, e) => 
{ 
     if (_notifyIcon != null) 
     { 
      _notifyIcon.Visible = false; 
      _notifyIcon.Dispose(); 
      _notifyIcon = null; 
     } 
}; 
+0

Trên cửa sổ đóng sự kiện, nó làm việc cho tôi. Trên App_Exit nó ném lỗi trong khi xử lý notifyIcon. – Sunil

+1

chỉ cần bọc nó trong một thử bắt và bỏ qua các ngoại lệ –

11

Trên Windows 7, tôi cũng phải đặt thuộc tính Biểu tượng thành không. Nếu không, biểu tượng vẫn còn trong cửa sổ "biểu tượng ẩn" của khay sau khi ứng dụng đã đóng. HTH ai đó.

// put this inside the window's class constructor 
Application.ApplicationExit += new EventHandler(this.OnApplicationExit); 


     private void OnApplicationExit(object sender, EventArgs e) 
     { 

      try 
      { 
       if (trayIcon != null) 
       { 
        trayIcon.Visible = false; 
        trayIcon.Icon = null; // required to make icon disappear 
        trayIcon.Dispose(); 
        trayIcon = null; 
       } 

      } 
      catch (Exception ex) 
      { 
       // handle the error 
      } 
     } 
+0

cùng là đúng cho Windows 8. tốt bắt :) – Ovais

+2

Đây là giải pháp làm việc. Cảm ơn. –

0

Bạn đã ghi đè phương thức vứt bỏ đối tượng nơi bạn đã khởi tạo notificationIcon cũng để hủy bỏ notifyIcon?

protected override void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     notifyIcon.Dispose(); 
     notifyIcon = null; 
    } 
    base.Dispose(disposing); 
} 
0

Mã này làm việc cho tôi

this.Closed += (a, b) => 
      { 
       if (notifyIcon1 != null) 
       { 
        notifyIcon1.Dispose(); 
        notifyIcon1.Icon = null; 
        notifyIcon1.Visible = false; 
       } 
      }; 
Các vấn đề liên quan