ContextMenuStrip – Dynamisch Separatoren anzeigen oder ausblenden (C#)

In diesem Artikel möchte ich eine Methode vorstellen mit welcher je nach sichtbaren Menüpunkten eines Kontextmenüs die Separatoren zwischen einzelnen Menügruppen angezeigt (visible == true) bzw ausgeblendet (visibel == false) werden.

Schauen wir uns doch zuerst einmal an um was es dabei wirklich geht.

Hier zuerst das Gesamte Menü mit allen Möglichen Menüpunkten.

Dieses Beispiel stellt das Kontextmenü einer Anwendung dar, die verschiedene Kalendereinträge enthalten kann.

Je nachdem welche Art Kalendereintrag (Planung, Anlieferung, Sperrzeit etc.) ausgewählt wurde und welche Berechtigungen ein Benutzer besitzt werden nur bestimmte Menüpunkte aus dieser Gesamtauswahl angezeigt.

Häufig wird das so geregelt, dass man anstelle die Menüpunkte auszublenden diese nur deaktiviert. In diesem Fall ist es dann nicht notwendig sich Gedanken darüber zu machen einzelne Separatoren für eventuell ganz wegfallende Menügruppen zu entfernen.

Nachfolgend nun einige Abbildungen die anzeigen was passiert wenn man die Menüpunkte ausblendet ohne sich um die Separatoren zu kümmern.

Man beachte die vielen direkt aufeinander folgenden Separatoren, Sieht nicht wirklich Professionell aus.

Nun kann man natürlich die Separatoren ebenfalls im Opening Event manuell Sichtbar oder Unsichtbar machen (setzen der Visible Eigenschaft), dass kann aber je nach Komplexität der Menüstruktur sehr schnell sehr mühsam und sehr fehleranfällig werden.

Genau aus diesem Grund habe ich mir hierzu eine Methode erstellt die sich um diese Aufgabe selbstständig kümmert und je nach sichtbaren Menüpunkten die benötigten Separatoren ebenfalls sichtbar oder unsichtbar macht.

Doch bevor ich die Methode zeige, möchte ich zuerst das Ergebnis anhand der nachfolgenden Abbildungen zeigen. Hier nun die korrekt dargestellten Menüs.

Das sieht doch schon viel besser aus !

So nun aber der Quellcode der Methode.

internal static void SetToolStripSeperatorForContextMenu(ContextMenuStrip contextMenuStrip)
{
	bool isVisible = false;
	int seperatorIndex = 0;
	for (int i = 0; i < contextMenuStrip.Items.Count; i++)
	{
		if (contextMenuStrip.Items[i] is ToolStripSeparator)
		{
			contextMenuStrip.Items[i].Visible = false;
		}

		if (contextMenuStrip.Items[i].Available)
		{
			if (seperatorIndex > 0)
			{
				contextMenuStrip.Items[seperatorIndex].Visible = true;
				seperatorIndex = 0;
			}
			isVisible = true;
		}
		if (contextMenuStrip.Items[i] is ToolStripSeparator)
		{
			if (isVisible)
			{
				seperatorIndex = i;
			}
			isVisible = false;
		}
	}
}

Übrigens die Methode einfach am Ende des Opening Event des Kontextmenüs wie folgt aufrufen.

SetToolStripSeperatorForContextMenu(((ContextMenuStrip) sender));

Und fertig.

Code Optimierung – Teil 1250 (in C# geht auch Spaghetti kodierung)

Ich bin zur Zeit, unter anderem damit beauftragt ein Projekt für einen Kunden zu überarbeiten und zu optimieren.

In diesem Zusammenhang bin ich Heute Morgen auf ein Stück Quellcode gestoßen der mich sofort an die früher (so vor 20 Jahren) sehr üblichen Spaghetti Code Programme erinnert hat.

Ich zeige hier einfach mal den Code dieser Methode wie ich sie vorgefunden habe und anschließend die von mir leicht überarbeitete Methode.

Die Methode wird übrigens dazu verwendet verschiedene Button ein und auszublenden, sowie in Abhängigkeit von Datenfeldern einer Datenbank den Button mit einem Image zu verschönern und entsprechende Datums und Uhrzeiten anzuzeigen oder auszublenden.
Ich denke anhand der nachfolgenden Abbildungen kann man sich ungefähr vorstellen was die Methode macht.

Hier der doch etwas unübersichtliche Code

#region Ankunft

if (entladung.AnkunftLKW.HasValue)
{
	dtpAnkunftDate.Visible = true;
	dtpAnkunftTime.Visible = true;
}
else
{
	dtpAnkunftDate.Visible = false;
	dtpAnkunftTime.Visible = false;
}
#endregion

#region Einfahrt

if (entladung.EinfahrtLKW.HasValue)
{
	dtpEinfahrtDate.Visible = true;
	dtpEinfahrtTime.Visible = true;
}
else
{
	dtpEinfahrtDate.Visible = false;
	dtpEinfahrtTime.Visible = false;
}

#endregion

#region Entladung Start

if (entladung.EntladeStart.HasValue)
{
	dtpEntladungStartDate.Visible = true;
	dtpEntladungStartTime.Visible = true;
	btnEntladungStart.ImageIndex = 0;
	if (entladung.EntladeEnde.HasValue)
	{
		btnEntladungStart.Enabled = false;
	}
	else
	{
		btnEntladungStart.Enabled = true;
	}
}
else
{
	dtpEntladungStartDate.Visible = false;
	dtpEntladungStartTime.Visible = false;
}

#endregion

#region Entlade Ende

if (entladung.EntladeEnde.HasValue)
{
	dtpEntladungEndeDate.Visible = true;
	dtpEntladungEndeTime.Visible = true;
	btnEntladungEnde.ImageIndex = 0;

	btnEntladungEnde.Enabled = !entladung.AusfahrtLKW.HasValue;
}
 else
{
	if (entladung.EntladeStart.HasValue)
	{
		btnEntladungEnde.Enabled = true;
	}
	else
	{
		btnEntladungEnde.Enabled = false;
		btnEntladungEnde.ImageIndex = -1;
	}

	dtpEntladungEndeDate.Visible = false;
	dtpEntladungEndeTime.Visible = false;

}

#endregion

#region Ausfahrt

if (entladung.AusfahrtLKW.HasValue)
{
	dtpAusfahrtDate.Visible = true;
	dtpAusfahrtTime.Visible = true;
}
else
{
	dtpAusfahrtDate.Visible = false;
	dtpAusfahrtTime.Visible = false;
}

#endregion

Hier der Optimierte Code

dtpAnkunftDate.Visible = entladung.AnkunftLKW.HasValue;
dtpAnkunftTime.Visible = entladung.AnkunftLKW.HasValue;

dtpEinfahrtDate.Visible = entladung.EinfahrtLKW.HasValue;
dtpEinfahrtTime.Visible = entladung.EinfahrtLKW.HasValue;

dtpEntladungStartDate.Visible = entladung.EntladeStart.HasValue;
dtpEntladungStartTime.Visible = entladung.EntladeStart.HasValue;

dtpEntladungEndeDate.Visible = entladung.EntladeEnde.HasValue;
dtpEntladungEndeTime.Visible = entladung.EntladeEnde.HasValue;

dtpAusfahrtDate.Visible = entladung.AusfahrtLKW.HasValue;
dtpAusfahrtTime.Visible = entladung.AusfahrtLKW.HasValue;

btnEntladungStart.ImageIndex = entladung.EntladeStart.HasValue ? 0 : -1;

btnEntladungStart.Enabled = ((!entladung.EntladeStart.HasValue) |
						((entladung.EntladeStart.HasValue && !entladung.EntladeEnde.HasValue)));

btnEntladungEnde.ImageIndex = entladung.EntladeEnde.HasValue ? 0 : -1;

btnEntladungEnde.Enabled = (entladung.EntladeStart.HasValue && !entladung.AusfahrtLKW.HasValue);

Man beachte die Zeilenzahlen. Die obere Variante hat genau die 4 fache Anzahl Code.
Obwohl, schön aussehen tun die vielen If’s und Else schon :-)

Und da der untere Code viel kürzer und einfacher ist, braucht man auch nichts mehr mit Region umklammern.

c# – Splitt Container Collapse Panel Advanced Example – WinForm

Galerie

Diese Galerie enthält 3 Fotos.

In einem aktuellen Projekt hat sich der Kunde gewünscht, ein “platzsparendes” Winform, zur Anzeige von Kalenderinformationen, zu erhalten. Und da der Wunsch des Kunden gleich einem Befehl ist…. Voila ! Hier (m)ein Lösungsansatz. Und da ich denke, dass auch im … Weiterlesen

c# – tabControl – tabPage – Fehlende Visible Eigenschaft

Wer in WinForms Anwendungen das tabControl einsetzt wird über kurz oder lang darüber stolpern, dass die tabPage Controls keine Visible Eigenschaft besitzen.

Das bedeute es ist weder in der Entwicklungsumgebung noch zur Laufzeit Möglich einfach durch setzen der Visible Eigenschaft einzelne tabPage Seiten zwischen sichtbar und unsichtbar umzuschalten.

Hier daher ein kleines Code Snippet mit dem man die tabPage aus dem Programmcode heraus aus der tabPage Auflistung des tabControls entfernen oder hinzufügen kann.

// Hier der Code für Visible=False
tabControlOptionen.TabPages.Remove(tabUser);

// Hier der Code für Visible=True
tabControlOptionen.TabPages.Add(tabUser);