Laden...

TrayIcon ContextMenu: Wird beim klicken nicht angezeigt

Erstellt von Frokuss vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.155 Views
F
Frokuss Themenstarter:in
158 Beiträge seit 2015
vor 6 Jahren
TrayIcon ContextMenu: Wird beim klicken nicht angezeigt

Guten Tag,

ich habe da leider ein Problem mit meinem TrayIcon. An sich wird mir zwar mein TrayIcon angezeigt, aber beim klicken (links, rechts doppelt) tut sich einfach nichts. Daher: Es wir nicht das TrayIcon.ContextMenu angezeigt.

		public TrayIcon(){
			trayMenu = new ContextMenu();
			trayMenu.MenuItems.Add("Beenden", OnExit);
			trayIcon = new NotifyIcon();
			trayIcon.Text = "MyTrayApp";
			trayIcon.Icon = new Icon(SystemIcons.Information, 40, 40);

			trayIcon.ContextMenu = trayMenu;
			trayIcon.Visible = true;
		}

Eigentlich müsste doch wenn es richtig geht mit einem klick auf das Icon (ein runder Kreis mit einem "i" drinnen, sich das Menü mit dem Punkt "Beenden" öffnen, oder?

Ein hinzufügen von folgendem hat leider auch nichts gebracht. Daher es kommt nicht mal die MessageBox...

trayIcon.Click = new EventHandler(TestMich);

		private void TEST(object sender, EventArgs evt){
MessageBox.Show("hier...");
		}

Leider kann ich mir nicht ergründen, warum zwar das Icon angezeigt wird, aber das ContextMenu nicht angezeigt wird. Ich hoffe ihr könnt mir da weiter helfen 😃

Lieben Gruß
Frokuss

PS:folgendes kann ersetzt werden:
public class TrayIcon : MyForm
zu
public class TrayIcon : Form

1.040 Beiträge seit 2007
vor 6 Jahren

aber beim klicken (links, rechts doppelt)

Dein Code funktioniert, mache einfach mal einen Rechtsklick. 😉

F
Frokuss Themenstarter:in
158 Beiträge seit 2015
vor 6 Jahren

Mhhh... Das ist doof. Ich hätte mir lieber einen Fehler gewünscht 😦

Ich habe mein System nun neugestartet und das Problem besteht weiter hin. Egal welche Klickart (links, rechts oder und/oder doppelt) führt zu keinem Kontextmenü O.o

Kennt denn jemand eventuell Ursachen, warum zwar das Icon erzeugt wird, aber nicht das Kontextmenü angezeigt wird? Dummerweise wird auch keine Exeption geworfen...

Besten Gruß Frokuss

PS: Mit einer MessageBox kann ich aber angeben lassen, dass die Kontextmenüeinträge zugewiesen sind. Bedeutet: trayIcon.ContextMenu.MenuItems.Count ist größer 0.

1.040 Beiträge seit 2007
vor 6 Jahren

Dann musst du wohl mehr Code zeigen...

F
Frokuss Themenstarter:in
158 Beiträge seit 2015
vor 6 Jahren

Okay... Hier mal die komplette Klasse - wobei ich unwichtiges entfernt habe:

using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace ClientForm
{
	/// <summary>
	/// Description of TrayIcon_cs.
	/// </summary>
	public class TrayIcon : MyForm//kann zu >>public class TrayIcon : Form<< ersetzt werden
	{
		private NotifyIcon trayIcon;
		private ContextMenu trayMenu;
		private List <MyForm> fenster;
		private int contentPages;
		
		public TrayIcon(){			
			trayMenu = new ContextMenu();
			//trayMenu.MenuItems.Add("Freunde", OnClickItem);
			//trayMenu.MenuItems.Add("Einstellungen", OnClickEin);
			trayMenu.MenuItems.Add("Beenden", OnExit);
			trayIcon = new NotifyIcon();
			trayIcon.Text = "MyTrayApp";
			trayIcon.Icon = new Icon(SystemIcons.Information, 40, 40);

			trayIcon.ContextMenu = trayMenu;
			trayIcon.Visible = true;
			fenster = new List<MyForm>();
		}
		
		private bool FindFormByName(string name){
			bool check = false;
			foreach(Form item in fenster){
				if(item.Name == name){//besser Equals...
					item.Show();
					item.BringToFront();
					
					check = true;
					break;
				}
			}
			return check;
		}
		
		private void OnExit(object sender, EventArgs evt){
			Application.Exit();
		}
		
        protected override void OnLoad(EventArgs evt) {
            Visible = false;
            ShowInTaskbar = false;

            base.OnLoad(evt);
        }
		
        protected override void Dispose(bool isDisposing){
            if(isDisposing)
            	trayIcon.Dispose();
            
            base.Dispose(isDisposing);
        }
		
		private void OnClickItem(object sender, EventArgs evt){
			string name = "Titel";
			bool check = FindFormByName(name);
			if(!check){
//Hier Fenster (Form) erzeugen
			}
		}
	}
}

MyForm ermöglicht mir, dass Fenster Blinken können... Wenn nötig kann ich auch das posten...

Lieben Gruß Frokuss

PS: folgendes kann ersetzt werden:
public class TrayIcon : MyForm
durch
public class TrayIcon : Form

1.040 Beiträge seit 2007
vor 6 Jahren

Also mit Form als Basisklasse funktioniert auch der Code.

709 Beiträge seit 2008
vor 6 Jahren

Wenn ich deinen Code in eine neue Form kopiere, läuft das ohne Probleme.
Einzig MyForm habe ich durch Form ersetzt.

F
Frokuss Themenstarter:in
158 Beiträge seit 2015
vor 6 Jahren

Genau das ist ja mein Problem 😄 Ich kann mir nicht erklären, warum sich das Kontextmenü nicht öffnet. Auch ich habe getestet, ob es in einer seperaten Klasse geht... Und es geht O.o

Aber komischerweise zeigt mir

			foreach(MenuItem item in trayIcon.ContextMenu.MenuItems){
				MessageBox.Show(item.Text);
			}

Alle hinzugefügten Elemente an... Und das verwundert mich.

Gruß Frokuss

F
Frokuss Themenstarter:in
158 Beiträge seit 2015
vor 6 Jahren

Also... Ich konnte den Fehler einwenig eingrenzen 😃

Und zwar habe ich eine Klasse Verbindung, die einen Thread erstellt... Und in dem Teil, in dem der Thread läuft, führt dies zu dem eigenartigen Verhalten. Hier der Code wo ich das TrayIcon mit ContextMenu habe...

		public Verbindung(){
			hostInfo = Dns.GetHostByName(host);
			ep = new IPEndPoint(hostInfo.AddressList[0],port);
			lauscher = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
		}

		public Verbindung(string pw) : this(){
			int count = 1;
			do{
				if(!Connect2Server())
					count++;
				
				if(count >= 3){
					serverDown = true;
					Thread.Sleep(2000);
					break;
				}
				Thread.Sleep(2000);
			}while(!lauscher.Connected);
			
			if(lauscher.Connected){
				thread = new Thread(delegate(){Starten(lauscher, pw);});
				thread.Start();
			}
		}

Und hier, wo entweder Fehler geworfen werden, oder das ContextMenu nicht angezeigt werden:

		public void Starten(Socket server, string pw){		
			this.server = server;
			MyStream ms = new MyStream(server);
			Nachricht nachricht;

			Login(pw, true);
			
			while(!auth && !beenden)
				Thread.Sleep(1500);
			
//Hier findet noch eine Datenaustausch mit dem Server statt - Die Daten fließen
//aber (noch) nicht in das TrayIcon hinein. Daher irrelevant (und bei mir eh auskommentiert)

			if(!beenden){
				Thread.Sleep(50);
				//myIcon = new TrayIcon();
			}
			
			while(!beenden){
				Thread.Sleep(2000);
			}
			MessageBox.Show("Ende...");
		}

getestet habe ich das mit:

new TrayIcon();
16.807 Beiträge seit 2008
vor 6 Jahren

Was auch immer Verbindung wirklich ist: hübsch geht anders. 😉
In diesem Fall, was man so sieht, auch falsch.

Du führst wohl im GUI Thread die do-while-Schleife aus, in der Du ein Thread.Sleep hast.
Den eigentlichen Thread startest Du erst danach.
Das bedeutet: Deine GUI kann nicht reagieren, weil Du hier Threads (und entsprechende Schleifen) falsch behandelst.

Hier stimmen die Basics zu Threads definitiv nicht. 😃