Manifest in ein Projekt einbinden

Häufig ist es notwendig, dass man einer Anwendung Adminrechte gibt, wenn diese zum Beispiel Netzwerkzugriffe, Registryeingriffe usw. tätigen muss. Dazu muss man eine Anwendungsmanifestdatei in die exe-Datei einkompilieren, in welcher die entsprechenden Benutzerrechte für die Windows-UAC eingetragen sind.

Variante 1:

  1. In Visual Studio 2010 besteht die Möglichkeit eine Manifestdatei erzeugen lassen: im Projekt Rechtsklick auf das Projekt->Hinzufügen->Neues Element …->Anwendungsmanifestdatei. Visual Studio erzeugt unten stehende Datei, wobei die entsprechend benötigten Zeilen aus- bzw. einkommentiert werden müssen:
    <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?->
    <asmv1:assembly manifestVersion=&quot;1.0&quot; xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; xmlns:asmv1=&quot;urn:schemas-microsoft-com:asm.v1&quot; xmlns:asmv2=&quot;urn:schemas-microsoft-com:asm.v2&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;->
      <assemblyIdentity version=&quot;1.0.0.0&quot; name=&quot;MyApplication.app&quot;/->
      <trustInfo xmlns=&quot;urn:schemas-microsoft-com:asm.v2&quot;->
        <security->
          <requestedPrivileges xmlns=&quot;urn:schemas-microsoft-com:asm.v3&quot;->
            <!-- UAC-Manifestoptionen
              Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den 
              requestedExecutionLevel-Knoten durch eines der folgenden Elemente.
    
            <requestedExecutionLevel  level=&quot;asInvoker&quot; uiAccess=&quot;false&quot; /->
            <requestedExecutionLevel  level=&quot;requireAdministrator&quot; uiAccess=&quot;false&quot; /->
            <requestedExecutionLevel  level=&quot;highestAvailable&quot; uiAccess=&quot;false&quot; /->
    
                Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert.
                Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts- 
                kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten.
            -->
            <requestedExecutionLevel level=&quot;asInvoker&quot; uiAccess=&quot;false&quot; /->
          </requestedPrivileges->
        </security->
      </trustInfo->
      
      <compatibility xmlns=&quot;urn:schemas-microsoft-com:compatibility.v1&quot;->
        <application->
          <!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist. Windows wählt automatisch die am stärksten kompatible Umgebung aus.-->
    
          <!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.-->
          <!--<supportedOS Id=&quot;{35138b9a-5d96-4fbd-8e2d-a2440225f93a}&quot;/->-->
          
        </application->
      </compatibility->
      
      <!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
      <!-- <dependency->
        <dependentAssembly->
          <assemblyIdentity
              type=&quot;win32&quot;
              name=&quot;Microsoft.Windows.Common-Controls&quot;
              version=&quot;6.0.0.0&quot;
              processorArchitecture=&quot;*&quot;
              publicKeyToken=&quot;6595b64144ccf1df&quot;
              language=&quot;*&quot;
            /->
        </dependentAssembly->
      </dependency->-->
    
    </asmv1:assembly->
    
  2. eine Anwendungsmanifestdatei für Windows 7 und mit Zugriffsrechten “Admin” sieht beispielhaft so aus:
    <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?->
    <asmv1:assembly manifestVersion=&quot;1.0&quot; xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; xmlns:asmv1=&quot;urn:schemas-microsoft-com:asm.v1&quot; xmlns:asmv2=&quot;urn:schemas-microsoft-com:asm.v2&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;->
      <assemblyIdentity version=&quot;1.0.0.0&quot; name=&quot;MyApplication.app&quot;/->
      <trustInfo xmlns=&quot;urn:schemas-microsoft-com:asm.v2&quot;->
        <security->
          <requestedPrivileges xmlns=&quot;urn:schemas-microsoft-com:asm.v3&quot;->
            <requestedExecutionLevel level=&quot;requireAdministrator&quot; uiAccess=&quot;false&quot; /->
          </requestedPrivileges->
        </security->
      </trustInfo->
      
      <compatibility xmlns=&quot;urn:schemas-microsoft-com:compatibility.v1&quot;->
        <application->
          <supportedOS Id=&quot;{35138b9a-5d96-4fbd-8e2d-a2440225f93a}&quot;/->
        </application->
      </compatibility->
      
      <!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
      <!-- <dependency->
        <dependentAssembly->
          <assemblyIdentity
              type=&quot;win32&quot;
              name=&quot;Microsoft.Windows.Common-Controls&quot;
              version=&quot;6.0.0.0&quot;
              processorArchitecture=&quot;*&quot;
              publicKeyToken=&quot;6595b64144ccf1df&quot;
              language=&quot;*&quot;
            /->
        </dependentAssembly->
      </dependency->-->
    
    </asmv1:assembly->
    
  3. Die Manifestdatei muss unter Projektbaum->Eigenschaften->Anwendung->Symbol und Manifest->Manifest (Datei “app.manifest”) ausgewählt sein, damit sie von Visual Studio mit in die Anwendung einkompiliert wird.
  4. Die im Ausgabeverzeichnis fertig kompilierte Anwendung sollte nun ein Security-Schild im Icon haben.
  5. Nach dem Start der Anwendung fragt Windows-UAC nun, ob das Programm mit Adminrechten ausgeführt werden darf.

Variante 2:

  1. Diese manuelle Variante funktioniert nur mit VS Standard oder Professional, nicht mit Express, da bei letzterem keine Post Build Events eingestellt werden können.
  2. Manifestdatei in einem Editor erzeugen, Projektnamen bei “name” korrekt eintragen, Prozessorarchitektur anpassen und im Ausgabeverzeichnis des Projektes speichern. Eine Beispieldatei zum Erlangen von Adminrechten siehe oben unter Punkt 2 bei Varante 1.
  3. Mittels mt.exe wird nun die Manifestdatei in die ausführbare Datei als Win32-Resource eingebunden. Die prinzipielle Kommandozeile dazu lautet:
    mt.exe –manifest temp.manifest –outputresource:YourApp.exe;#1
    

    Dazu unter Projektbaum->Projekt->Eigenschaften->Buildereignisse->Befehlszeile für Postbuild-Ereignis folgende Zeile eintragen:

    "$(DevEnvDir)..\..\SDK\v2.0\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest"  –outputresource:"$(TargetDir)$(TargetFileName)";#1
    

    bei anderen VS-Versionen alternativ auch:

    "c:\Programme\Microsoft SDKs\Windows\v7.0A\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest"  –outputresource:"$(TargetDir)$(TargetFileName)";#1
    
  4. Die im Ausgabeverzeichnis fertig kompilierte Anwendung sollte nun ein Security-Schild im Icon haben.
  5. Nach dem Start der Anwendung frag Windows-UAC nun, ob das Programm mit Adminrechten ausgeführt werden darf.

Speicherauslastung (MEMORYSTATUSEX) auslesen

// Aufruf:
//
// MemInfo.MEMORYSTATUSEX ms = MemInfo.CurrentMemoryStatus;
//
// uint uiMemoryLoad = ms.dwMemoryLoad;
// ulong ulTotalPhys = ms.ulTotalPhysical;
// ulong ulAvailPhys = ms.ulAvailPhysical;
// ulong ulTotalPageFile = ms.ulTotalPageFile;
// ulong ulAvailPageFile = ms.ulAvailPageFile;
// ulong ulTotalVirtual = ms.ulTotalVirtual;
// ulong ulAvailVirtual = ms.ulAvailVirtual;
// ulong ulAvailExtendedVirtual = ms.ulAvailExtendedVirtual;

using System.Runtime.InteropServices;

/// <summary>
/// freeware helper class for getting memory info
/// (W) 2011 by admin of codezentrale.de
/// http://pinvoke.net/default.aspx/kernel32/GlobalMemoryStatusEx.html
/// http://msdn.microsoft.com/en-us/library/aa366589%28v=vs.85%29.aspx
/// </summary>
public static class MemInfo
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct MEMORYSTATUSEX
    {
        public uint dwLength;
        public uint dwMemoryLoad;
        public ulong ulTotalPhysical;
        public ulong ulAvailPhysical;
        public ulong ulTotalPageFile;
        public ulong ulAvailPageFile;
        public ulong ulTotalVirtual;
        public ulong ulAvailVirtual;
        public ulong ulAvailExtendedVirtual;
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);

    /// <summary>
    /// get current memory status struct
    /// </summary>
    public static MEMORYSTATUSEX CurrentMemoryStatus
    {
        get
        {
            MEMORYSTATUSEX ms = new MEMORYSTATUSEX();
            ms.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));

            GlobalMemoryStatusEx(ref ms);

            return ms;
        }
    }
}

Informationen über das akt. verwendete .NET-Framework abfragen

using System;
using System.IO;
using Microsoft.Win32;

/// <summary>
/// freeware helper class for getting .NET framework info
/// (W) 2011 by admin of codezentrale.de
/// </summary>
public static class NETFrameworkInfo
{
    /// <summary>
    /// prints the root install path of the .NET-Frameworks on your system
    /// </summary>
    /// <returns>.NET root install path</returns>
    public static string NETRootPath
    {
        get
        {
            string rootpath = string.Empty;

            try
            {
                RegistryKey rKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework");

                if (rKey != null)
                {
                    rootpath = rKey.GetValue("InstallRoot").ToString();
                }
            }
            catch (Exception e)
            {
                rootpath = e.Message;
            }

            return rootpath;
        }
    }
    /// <summary>
    /// prints currently used CLR version string
    /// hint: .NET 3.0 & 3.5 are using CLR v2.0!
    /// </summary>
    /// <returns>currently used CLR version</returns>
    public static string CurrentCLRVersion
    {
        get
        {
            return Environment.Version.ToString();
        }
    }
    /// <summary>
    /// prints the currently used .NET version home directory
    /// hint: .NET 3.0 & 3.5 are using CLR v2.0, so the homedir for the CLR-DLLs is v2.X !
    /// </summary>
    /// <returns>the currently used .NET version home directory</returns>
    public static string CurrentCLRVersionHome
    {
        get
        {
            string sRetVal = string.Empty;

            string sRootPath = NETRootPath;

            if (!string.IsNullOrEmpty(sRootPath))
            {
                sRetVal = Path.Combine(sRootPath, "v" + Environment.Version.Major.ToString() + "." + Environment.Version.Minor.ToString() + "." + Environment.Version.Build.ToString());

                if (!Directory.Exists(sRetVal))
                {
                    sRetVal = string.Empty;
                }
            }

            return sRetVal;
        }
    }
}

Registryeinträge lesen, schreiben, anlegen

using Microsoft.Win32;

// Beispiel für das Lesen der AutoRun-Einstellungen
RegistryKey rKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer");

if (rKey != null)
{
    object oKeyVal = rKey.GetValue("NoDriveTypeAutoRun");
}

// Beispiel für das Neuanlegen der AutoRun-Einstellungen
RegistryKey rKey = Registry.LocalMachine.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer");

if (rKey != null)
{
    rKey.SetValue("NoDriveTypeAutoRun", 189);
}

// Beispiel für das setzen der AutoRun-Einstellungen
RegistryKey rKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", true);

if (rKey != null)
{
    rKey.SetValue("NoDriveTypeAutoRun", 189);
}

Windows Betriebssystemversion ermitteln

using System;

/// <summary>
/// freeware helper class for getting OS info
/// (W) 2011 by admin of codezentrale.de
/// </summary>
public static class OSVersion
{
    /// <summary>
    /// version string for current system
    /// </summary>
    public static string VersionString
    {
        get
        {
            string sRetVal = string.Empty;

            Version osver = Environment.OSVersion.Version;

            switch (Environment.OSVersion.Platform)
            {
                // Windows 95 wird von .NET nicht unterstützt
                // Windows 98, Windows 98SE, Windows Me
                case PlatformID.Win32Windows:
                    if (osver.Major == 4)
                    {
                        switch (osver.Minor)
                        {
                            case 10: sRetVal = "Windows 98"; break;
                            case 90: sRetVal = "Windows Me"; break;
                        }
                    }
                    break;
                case PlatformID.Win32NT:
                    // Windows NT 3.51 wird von .NET nicht unterstützt
                    // Windows NT 4.0
                    if (osver.Major == 4) sRetVal = "Windows NT 4.0";

                    // Windows 2000, XP, Server 2003
                    if (osver.Major == 5)
                    {
                        switch (osver.Minor)
                        {
                            case 0: sRetVal = "Windows 2000"; break;
                            case 1: sRetVal = "Windows XP"; break;
                            case 2: sRetVal = "Windows Server 2003"; break;
                        }
                    }
                    // Windows Vista, Windows Server 2008, Windows 7
                    if (osver.Major == 6)
                    {
                        switch (osver.Minor)
                        {
                            case 0: sRetVal = "Windows Vista / Windows Server 2008"; break;
                            case 1: sRetVal = "Windows 7 / Windows Server 2008 R2"; break;
                            case 2: sRetVal = "Windows 8 / Windows Server 2012"; break;
                        }
                    }
                    break;
            }

            if (sRetVal == string.Empty) sRetVal = "unbekannte oder von .NET nicht unterstützte Windows-Version";
            else sRetVal += " [" + Environment.OSVersion.VersionString + ", rev " + osver.Revision.ToString() + "]";

            return sRetVal;
        }
    }
}

switch … case mit typeof

// value ist ein bel. Objekt
// es können allerdings nur die in TypeCode
// definierten Systemtypen behandelt werden
switch (Type.GetTypeCode(value.GetType()))
{
    case TypeCode.Boolean :
        break;
    case TypeCode.Char :
        break;
    case TypeCode.String :
        break;
    case TypeCode.DateTime :
        break;
    case TypeCode.Object :
        break;
    default :
        break;
}

mittels Help-Klasse CHM-Hilfedateien einbinden

Allgemein

// Hilfedatei anzeigen
Help.ShowHelp(this, @"c:\helpfile.chm");
// Hilfedatei anzeigen, zu Seite mit "keyword" springen
Help.ShowHelp(this, @"c:\helpfile.chm", "keyword");
// TopicID 1234 anzeigen
Help.ShowHelp(this, @"c:\helpfile.chm", HelpNavigator.Topic, "html\hs1234.htm");
// oder direkt über die TopicID, falls es die ID nicht gibt, wird nichts angezeigt,
// man sollte zuvor erst die Inhaltsübersicht anzeigen, damit wenigstens die
// Gesamtübersicht zu sehen ist
Help.ShowHelp(this, @"c:\helpfile.chm", HelpNavigator.TopicId, "1234");
// Inhaltsübersicht öffnen
Help.ShowHelp(this, @"c:\helpfile.chm", HelpNavigator.TableOfContents, "");
// Index der Hilfedatei anzeigen
Help.ShowHelpIndex(this, @"c:\helpfile.chm");
// kleines Hint-Window mit Hilfetext an best. Position anzeigen
Help.ShowPopup(this, "Hilfetext", new Point(100, 100));

Links

Clipboard (Zwischenablage) copy & paste

// Text in Zwischenablage kopieren
Clipboard.SetText("Testtext");

// CSV-Text in Zwischenablage kopieren
// CSV-Daten durch Tab trennen und als TextDataFormat.Text übergeben,
// Excel erkennt die Trennung automatisch am Tab und Newline
string sHeader = "Name\tVorname\tAlter";
string sData = "Horst\tHorstmann\t24";
Clipboard.SetText(sHeader + Environment.NewLine + sData, TextDataFormat.Text);

// Text aus Zwischenablage kopieren
string sText = Clipboard.GetText();

// Bild in Zwischenablage kopieren
Clipboard.SetImage(Image.FromFile(@"c:\Bild1.jpg"));

// Bild aus Zwischenablage kopieren
Image imgToCopy = Clipboard.GetImage();

// testen, ob Zwischenablage z.B. Text enthält
if (Clipboard.ContainsData(DataFormats.Text))
{
}

// Zwischenablage leeren
Clipboard.Clear();

Weiterführende Infos: Link

[C#] TabPage eines TabControls ein-/ausblenden

Standardmäßig gibt es kein Hide() oder Visible = true/false für TabPages. Man muss sich eines Tricks bedienen, bei dem die TabPages aus der internen Liste des TabControls gelöscht bzw. wieder hinzugefügt werden.

// TabPage "TabPage1", die zur Designzeit erstellt wurde, ausblenden
TabControl1.TabPages.Remove(TabPage1);

// TabPage "TabPage1", die zur Designzeit erstellt wurde, wieder am Anfang der Tabliste hinzufügen
TabControl1.TabPages.Add(TabPage1);

// TabPage "TabPage1", die zur Designzeit erstellt wurde, an zweiter Stelle in die Tabliste einfügen
TabControl1.TabPages.Insert(1, TabPage1);

Im Folgenden wird eine Klasse beschrieben, die automatisiert per Index immer nur eine bestimmte TabPage eines TabControls in Form eines schrittweise durchschaltbaren, geführten Einstellungsassistenten anzeigt. Am Ende wird ein Startbutton freigeschaltet.
Aufruf-Beispiel:

// alle zur Designzeit erstellten TabPages von TabControl1 werden verwaltet
// die Buttons btnPrevious und btnNext (müssen nicht angegeben werden) schalten die TabPages um
// der Button btnStart wird auf der letzten Seite freigeschaltet.
// "<-", "->" sind strings, die innerhalb der Buttons zusätzlich zum Namen angezeigt werden
// true == TabPage.Text + [1/x] anzeigen
CTabSelector _TabSelector = new CTabSelector(TabControl1, btnPrevious, btnNext, btnStart, "<-", "->", true);

// schaltet die TabPages zurück
private void btnBkwd_Click(object sender, EventArgs e)
{
    if (_TabSelector != null)
    {
        _TabSelector.CurrentTabIndex--;
    }
}
// schaltet die TabPages vor
private void btnFwd_Click(object sender, EventArgs e)
{
    if (_TabSelector != null)
    {
        _TabSelector.CurrentTabIndex++;
    }
}

Code:

/// <summary>
/// helper class for showing/hiding tabs in a TabControl
/// freeware (W) 2009 by SiteAdmin of www.codezentrale.6x.to
/// Usage:
/// private TabSelector _TabSelector = new TabSelector(TabControl1, btnPrevious, btnNext, btnStart, "<-", "->", true);
/// 
/// private void btnPrevious_Click(object sender, EventArgs e)
/// {
///    if (_TabSelector != null)
///    {
///        _TabSelector.CurrentTabIndex--;
///    }
/// }
/// private void btnNext_Click(object sender, EventArgs e)
/// {
///    if (_TabSelector != null)
///    {
///       _TabSelector.CurrentTabIndex++;
///    }
/// }
/// </summary>
class TabSelector
{
	#region vars
	private TabControl _tctrlTabControl = null;
	private int _iCurrentTabIndex = -1;
	private List<TabPage> _TabPages = new List<TabPage>();
	private List<string> _TabCaptions = new List<string>();
	private List<bool> _TabPageHidden = new List<bool>();
	private Button _btnPrevious = null;
	private Button _btnNext = null;
	private Button _btnFinal = null;
	private string _sPreviousItem = string.Empty;
	private string _sNextItem = string.Empty;
	private bool _bShowProgress = false;
	#endregion

	#region properties
	/// <summary>
	/// switches current shown tab by index, e.g. CurrentTabIndex++, CurrentTabIndex--
	/// </summary>
	public int SetCurrentTabIndex
	{
		get { return _iCurrentTabIndex; }
		set
		{
			if (_tctrlTabControl != null)
			{
				int iCurrentValue = value;

				// forwards
				if (iCurrentValue > _iCurrentTabIndex)
				{
					while (_TabPageHidden[iCurrentValue])
					{
						iCurrentValue++;
					}
				}
				else
					// backwards
					if (iCurrentValue < _iCurrentTabIndex)
					{
						while (_TabPageHidden[iCurrentValue])
						{
							iCurrentValue--;
						}
					}

				if (iCurrentValue >= 0 && iCurrentValue < _TabPages.Count)
				{
					_iCurrentTabIndex = iCurrentValue;
				}

				this.RefreshTabControl();
			}
		}
	}

	/// <summary>
	/// refreshes the current tabcontrol
	/// </summary>
	private void RefreshTabControl()
	{
		_tctrlTabControl.TabPages.Clear();

		int iShownTabPages = _TabPages.Count;

		for (int i = 0; i < _TabPages.Count; i++)
		{
			if (_TabPageHidden[i])
			{
				iShownTabPages--;
			}
		}

		int iHiddenTabPages = 0;

		for (int i = 0; i < _iCurrentTabIndex; i++)
		{
			if (_TabPageHidden[i])
			{
				iHiddenTabPages++;
			}
		}

		_TabPages[_iCurrentTabIndex].Text = _bShowProgress ? _TabCaptions[_iCurrentTabIndex] + " [" + (_iCurrentTabIndex + 1 - iHiddenTabPages).ToString() + "/" + iShownTabPages.ToString() + "]" : _TabCaptions[_iCurrentTabIndex];
		_tctrlTabControl.TabPages.Add(_TabPages[_iCurrentTabIndex]);

		if (_btnPrevious != null)
		{
			if ((_iCurrentTabIndex > 0) && (_iCurrentTabIndex < _TabPages.Count))
			{
				int iPrevIndex = _iCurrentTabIndex - 1;

				while (_TabPageHidden[iPrevIndex] && (iPrevIndex > 0))
				{
					iPrevIndex--;
				}

				_btnPrevious.Text = _sPreviousItem + _TabCaptions[iPrevIndex];
				_btnPrevious.Visible = true;
			}
			else
			{
				_btnPrevious.Text = string.Empty;
				_btnPrevious.Visible = false;
			}
		}

		if (_btnNext != null)
		{
			if ((_iCurrentTabIndex >= 0) && (_iCurrentTabIndex < _TabPages.Count - 1))
			{
				int iNextIndex = _iCurrentTabIndex + 1;

				while (_TabPageHidden[iNextIndex] && (iNextIndex < _TabPages.Count))
				{
					iNextIndex++;
				}

				_btnNext.Text = _TabCaptions[iNextIndex] + _sNextItem;
				_btnNext.Visible = true;
			}
			else
			{
				_btnNext.Text = string.Empty;
				_btnNext.Visible = false;
			}
		}

		_btnFinal.Visible = this.IsLastPage;
	}

	/// <summary>
	/// returns the name of the current previous tab
	/// </summary>
	public string PreviousTabPage
	{
		get
		{
			string sRetVal = string.Empty;

			if (_tctrlTabControl != null)
			{
				if (_iCurrentTabIndex > 0 && _iCurrentTabIndex < _TabPages.Count)
				{
					sRetVal = _TabCaptions[_iCurrentTabIndex - 1];
				}
			}

			return sRetVal;
		}
	}

	/// <summary>
	/// returns the name of the current next tab
	/// </summary>
	public string NextTabPage
	{
		get
		{
			string sRetVal = string.Empty;

			if (_tctrlTabControl != null)
			{
				if (_iCurrentTabIndex >= 0 && _iCurrentTabIndex < _TabPages.Count - 1)
				{
					sRetVal = _TabCaptions[_iCurrentTabIndex + 1];
				}
			}

			return sRetVal;
		}
	}

	/// <summary>
	/// is the current shown page the first
	/// </summary>
	public bool IsFirstPage
	{
		get { return (_iCurrentTabIndex == 0); }
	}

	/// <summary>
	/// is the current shown page the last
	/// </summary>
	public bool IsLastPage
	{
		get { return (_iCurrentTabIndex == _TabPages.Count - 1); }
	}
	#endregion

	/// <summary>
	/// constructor of tabselector object
	/// </summary>
	/// <param name="tctrlTabControl">a TabControl whose tabs should be switched</param>
	/// <param name="btnPrevious">a button that switches the tabs backwards, could also be null</param>
	/// <param name="btnNext">a button that switches the tabs forwards, could also be null</param>
	/// <param name="btnFinal">a button that is shown at the end</param>
	/// <param name="sPreviousItem">string that should be added before every tabstring that is shown in btnPrevious, could also be empty</param>
	/// <param name="sNextItem">string that should be added after every tabstring that is shown in btnNext, could also be empty</param>
	/// <param name="bShowProgress">show current page number every tab</param>
	public TabSelector(TabControl tctrlTabControl, Button btnPrevious, Button btnNext, Button btnFinal, string sPreviousItem, string sNextItem, bool bShowProgress)
	{
		_tctrlTabControl = tctrlTabControl;
		_btnFinal = btnFinal;
		_btnFinal.Visible = false;

		if (_tctrlTabControl != null)
		{
			for (int i = 0; i < _tctrlTabControl.TabPages.Count; i++)
			{
				_TabPages.Add(_tctrlTabControl.TabPages[i]);
				_TabCaptions.Add(_tctrlTabControl.TabPages[i].Text);
				_TabPageHidden.Add(false);
			}

			if (_tctrlTabControl.TabPages.Count > 0)
			{
				_bShowProgress = bShowProgress;

				_tctrlTabControl.TabPages.Clear();
				_tctrlTabControl.TabPages.Add(_TabPages[0]);

				if (btnPrevious != null)
				{
					_btnPrevious = btnPrevious;
					if (sPreviousItem != string.Empty)
					{
						_sPreviousItem = sPreviousItem + " ";
					}
				}

				if (btnNext != null)
				{
					_btnNext = btnNext;
					if (sNextItem != string.Empty)
					{
						_sNextItem = " " + sNextItem;
					}
				}

				this.SetCurrentTabIndex = 0;
			}
		}
	}
	/// <summary>
	/// hide a given tabpage
	/// </summary>
	/// <param name="Page">the tabpage to hide</param>
	public void HideTabPage(TabPage Page)
	{
		int iFoundIndex = _TabPages.IndexOf(Page);

		if (iFoundIndex >= 0)
		{
			_TabPageHidden[iFoundIndex] = true;

			this.RefreshTabControl();
		}
	}
	/// <summary>
	/// show again a given tabpage
	/// </summary>
	/// <param name="Page">the tabpage to show again</param>
	public void ShowTabPage(TabPage Page)
	{
		int iFoundIndex = _TabPages.IndexOf(Page);

		if (iFoundIndex >= 0)
		{
			_TabPageHidden[iFoundIndex] = false;

			this.RefreshTabControl();
		}
	}
}

Tooltips für beliebige Controls anzeigen

Standardverfahren – automatisiert

  • ToolTip – Control aus der Toolbox auf ein Formular ziehen, Name ist standardmäßig toolTip1
  • alle Tooltip-fähigen Controls (Buttons, Labels …) zeigen nun unter Eigenschaften->Sonstiges ein Textfeld zur Eingabe eines Tooltips (“ToolTip auf toolTip1), hier kann der TooltipText für das jeweilige Control eingegeben werden

Tooltip per die MausEvents anzeigen lassen – manuell

  • ToolTip – Control aus der Toolbox auf ein Formular ziehen, Name ist standardmäßig toolTip1
  • Beispielcode für z.B. ein Label “label1”:
  • // Offset für das Anzeigen des ToolTips
    private const int TOOLTIPP_Y_OFFSET = 24;
    
    // beim Überfahren des Controls ToolTip anzeigen
    private void label1_MouseMove(object sender, MouseEventArgs e)
    {
        Label lbl = sender as Label;
    
        if (lbl != null)
        {
            // ToolTip unterhalb des Labels anzeigen
            toolTip1.Show("Ich bin ein Tooltip", lbl, e.X, e.Y + TOOLTIPP_Y_OFFSET);
        }
    }
    
    // beim Verlassen des Controls ToolTip ausblenden
    private void label1_MouseLeave(object sender, EventArgs e)
    {
        Label lbl = sender as Label;
    
        if (lbl != null)
        {
            // TooltTip ausblenden
            toolTip1.Hide(lbl);
        }
    }