c# – Windows 7 – Lokale IPV4 Adresse ermitteln

Einige meiner Tools (darunter vor allem eine Monitorprogramm zur Überwachung von Windows Diensten auf Basis eines UDP TraceListener) funktionieren unter Windows 7 nicht mehr korrekt.

Besser gesagt, beim versucht die lokale IP Adresse zu ermitteln tritt folgender Fehler auf:

{System.Net.Sockets.SocketException: Es wurde eine Adresse verwendet, die mit dem angeforderten Protokoll nicht kompatibel ist
   bei System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   bei System.Net.Sockets.Socket.Bind(EndPoint localEP)

 

Der nachfolgende Code Ausschnitt hat unter Windows XP noch einwandfrei funktioniert:

HostIP = Dns.GetHostAddresses(Dns.GetHostName())[0];
endPoint = new IPEndPoint(HostIP, _Port);
UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPSocket.Bind(endPoint);

Unter Windows 7 wird aber dabei eine IPV6 Adresse zurückgegeben, mit welcher das Binden des UPD Socket nicht funktioniert.

Nachfolgend nun eine Methode die sowohl unter Windows XP (und den anderen älteren Betriebssystemen) als auch den aktuellen Betriebssystemen wie Windows 7 und W2K8 Server  funktioniert.

foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
    if (address.AddressFamily != AddressFamily.InterNetworkV6)
    {
        HostIP = address;
        break;
    }
}
endPoint = new IPEndPoint(HostIP, _Port);
UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPSocket.Bind(endPoint);

C# – Combobox Anzeige von mehreren kombinierten Datenfeldern (DisplayMemeber)

Vor kurzem wurde im Zuge eines Projektes  (Unterstützung eines Entwickler Teams für eine Winform Anwendung im Logistikumfeld) unter anderem die Anforderung an mich heran getragen, dass der Kunde die Ansprechpartner für eine bestimmte Logistische Aktivität aus einer Combobox auswählen möchte.

Hierbei sollte in der Combobox, nicht nur ein Feld aus der Datenbank angezeigt werden, sondern die Anzeige sollte aus insgesamt 2 Feldern zusammengebaut werden.

Das Format sollte so aussehen: Nachname, Vorname

Hier ein Beispiel:

Mustermann, Hans

Dabei sollte die Lösung vollkommen im Client implementiert sein und nicht durch eine geänderte Abfrage der Datenbank realisiert werden.

Nun ist es aber so, dass man dem DisplayMember nur ein Feld der Datengebundenen Tabelle (Objekt) zuweisen kann und nicht mehrere oder sogar wie hier gewünscht diese Felder auch noch in einem bestimmten Format.

Sicherlich könnte man sich ein eigenen Objekt (List Objekt) erzeugen welches man dann als Datenquelle für die Bindung verwendet, aber es geht auch (viel) einfacher.

Hierzu verwenden wir dem Format Event der Combobox.

Dieser Event bekommt zwei Parameter mit übergeben:

object sender

ListControlConvertEventArgs e

Wobei wir für die hier beschriebene Lösung lediglich den ListControlConvertEventArgs Parameter benötigen und auch verwenden.

in e.ListItem wird das Datengebundene Objekt übergeben und in e.Value kann man den gewünschten Wert zurückgeben.

Hier ein zusammenhängendes Beispiel:

private void cmbSpediteurKontakt_Format(object sender, ListControlConvertEventArgs e)
{
	// Hier caste ich mir den übergeben Wert in das original Objekt
	var spediteurKontakt = ((SpediteureKontakte) e.ListItem);  
	// Und nun bastele ich mir die gewünschet Anzeige zusammen
	e.Value = String.Format("{0}, {1}", spediteurKontakt.Nachname, spediteurKontakt.Vorname);
}

Und das Ergebnis sieht dann so aus:

image

C# – DateTimePicker – UpDown – fehlende Eigenschaft Increment nachgebildet

In einer Windows Anwendung wird in einer Form unter anderem ein (eigentlich sind es zwei, aber dazu später mehr) DateTimePicker verwendet um Termine einzugeben.

Da der DateTimePicker nicht gerade komfortabel ist um sowohl Datum als auch Uhrzeiten einzugeben, wird ein DateTimePicker in der Option DropDownCalender (das ist deaktivierte Eigenschaft ShowUpDown) eingesetzt um das Datum elegant aus dem DropDownCalender auszuwählen und ein zweites DateTimePicker Control mit der gesetzen Eigenschaft ShowUpDown und dem entsprechenden Custom Format HH:mm um nur die Uhrzeit mit den Pfeilen hoch und runter einstellen zu können.

image

Nun ist es aber so, dass man im DateTimePicker keinen Inkrement Wert eingeben kann, um den die Minuten erhöht bzw vermindert werden wenn man einmal auf den Pfeil hoch oder runter klickt. Somit wird jeweils um eine Minute hoch oder runter gezählt.

In meinem Fall nun wollte der Kunde aber das Termine nicht Minutengenau sondern immer auf 15 Minuten (Viertelstunde) Basis, also 00, 15, 30 und 45 erfasst werden können.

Da ich nicht gleich ein eigenen Control entwickeln wollte, habe ich einfach eine kleine Routine in den Change Event des DateTimePicker eingebaut.

Nachfolgend der Code Ich denke die Routine ist selbsterklärend

private void startzeitTimePicker_ValueChanged(object sender, EventArgs e)
{
    DateTimePicker dtp = (DateTimePicker)sender;
    // Wenn nicht Minute nicht 0,15,45 oder 60 dann müssen wir was tun
    if ((((dtp.Value.Minute != 0) && (dtp.Value.Minute != 15)) && (dtp.Value.Minute != 30)) &&
        (dtp.Value.Minute != 45))
    {
        // Auch noch einfach, nur 14 Minuten drauf und gut ist
        if ((dtp.Value.Minute == 1) || (dtp.Value.Minute == 16) || (dtp.Value.Minute == 31) || (dtp.Value.Minute == 46))
        {
            dtp.Value = dtp.Value.AddMinutes(14);
        }
        else
        {
            // Zeit wurde heruntergezählt.
            if ((dtp.Value.Minute == 14) || (dtp.Value.Minute == 29) || (dtp.Value.Minute == 44) || (dtp.Value.Minute == 59))
            {
                int x = 14;     // Deshalb auf jeden Fall mal 14 Minuten abziehen,
                if (dtp.Value.Minute == 59)  // und wenn die Minuten auf 59 stehen, dann muss noch eine Stunde (60 minuten) mehr abgezogen werden
                {
                    x += 60;
                }
                dtp.Value = dtp.Value.AddMinutes(-x);
            }
            else // Wert muss manuell eingegeben worden sein, dann runden wir auf die nächst höhere Viertelstunde
            {
                for (int i = 0; i < 15; i++)
                {
                    int x = dtp.Value.Minute + i;
                    if ((x == 15) || (x == 30) || (x == 45) || (x == 60))
                    {
                        dtp.Value = dtp.Value.AddMinutes(i);
                        break;
                    }
                }
            }
        }
    }
}

Hoffe das hilft dem einen oder anderen (Oder mir selbst beim nächsten mal wenn ich vor dem gleichen Problem stehen Wink)

C# – ArrayList.Sort mit Komplexen Klassen (IComparer Implementierung)

In einer Anwendung verwende ich eine Klasse um die Appointmens eines Kalenders abzubilden. Diese Klasse ist relativ Komplex und um diesen Beitrag nicht ebenfalls zu komplex werden zu lassen, verwende ich hier eine (sehr) abgespeckte Version dieser Klasse um das Thema Sortierung einer ArrayListe von Komplexen Objekten zu veranschaulichen.
Die Verwendung einer ArrayList war hier zwingend vorgeschrieben (typisierte Listen List<Type> kamen nicht in Frage)

Zuerst einmal die Aufgabenstellung:

In einer ArrayListe (nennen wir Sie AppointmentList) befinden sich Termine in Form von Objekten (nennen wir sie Appointment). Diese Objekte haben unter anderem eine Eigenschaft (Property) Startdatum (vom Type DateTime).

Da die Appointment in der AppointmentList unsortiert vorliegen und eine Sortierung (eigentlich zwei Sortierungen Auf und Absteigend) nach dem Startdatum des Termins benötigt wird, bestand die Aufgabe die AppointmentList zu sortieren.

Die ArrayLIst verfügt über eine Methode Sort. Da es sich bei den zu sortierenden Objekten aber um ein Komplexe Klasse handelt, muss man der Sort Methode einen Comparer an die Hand geben, damit die Methode Sort Ihre Aufgabe durchführen kann.

Hier nun die Umsetzung:

Zuerst einmal die (komplexe) Klasse Appointment (eine abgespeckte Variante)

public class Appointment
{

    public Appointment()
    {
        appointmentGUID = Guid.NewGuid();
    }


    private readonly Guid appointmentGUID = new Guid("00000000000000000000000000000000");

    public Guid AppointmentGUID
    {
        get { return appointmentGUID; }
    }

    private DateTime startDate;

    public DateTime StartDate
    {
        get { return startDate; }
        set
        {
            startDate = value;
            OnStartDateChanged();
        }
    }

    protected virtual void OnStartDateChanged()
    {
    }


    private DateTime endDate;

    public DateTime EndDate
    {
        get { return endDate; }
        set
        {
            endDate = value;
            OnEndDateChanged();
        }
    }

    protected virtual void OnEndDateChanged()
    {
    }



    private string title = "";

    [DefaultValue("")]
    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            OnTitleChanged();
        }
    }

    protected virtual void OnTitleChanged()
    {
    }


    public override string ToString()
    {
        return Title;
    }

}

Der Comparer für diese Aufgabe sieht dann so aus (Methode zum Sortieren mit Implementierung der IComparer Schnittstelle:

public class AppointmentComparer : IComparer
{
    private bool descendSorting;
    public AppointmentComparer(bool descend)
    {
        descendSorting = descend;
    }

    int IComparer.Compare(object a, object b)
    {
        var b1 = (Appointment)a;
        var b2 = (Appointment)b;

        if (descendSorting)
        {
            return DateTime.Compare(b2.StartDate, b1.StartDate);
        }
        else
        {
            return DateTime.Compare(b1.StartDate, b2.StartDate);
        }
    }

}

Und verwenden kann man diesen Comparer wie folgt:

al.Sort(new AppointmentComparer(false));
            al.Sort(new AppointmentComparer(true));

al wurde dabei wie folgt deklariert:

ArrayList al = new ArrayList();

c# – .NET 2.0 – Anwendungseinstellungen im Bereich Anwendung – Schreibgeschütz

Auch wenn wir uns im Zeitalter von NET Framework 3.5 befinden ist dieser Beitrag in der Überschrift mit .NET 2.0 beschrieben, da sich in an dem Konzept der Anwendungseinstellungen seit .NET 2.0 keine Änderungen ergeben haben.

Mit dem Konzept der Anwendungseinstellungen wurde ein mehr oder weniger durchgängiges Konzept zur Speicherung und Verwendung von Anwendungs- und Benutzerspezifischen Daten eingeführt.

Bei der Einstellungen für eine Anwendung wird dabei zwischen zwei Bereichen (Benutzer / Anwendung) unterschieden.

Im Bereich Benutzer können die Einstellungen aus dem Programmcode sowohl gelesen als auch geschrieben werden.

Beispiel (Überprüfen ob eine Einstellung korrekt ist, wenn nicht dann aktualisieren und speichern):

// Lagereinheit Report
reportName = Settings.Default.Lagereinheit_ReportName;
if (!File.Exists(reportName))
{
    string tempName = File.GetFilenName(reportName);
    tempName = Application.StartupPath + "\\Reports\\" + tempName;
    if (File.Exists(tempName))
    {
        Settings.Default.Lagereinheit_ReportName = tempName;
        Settings.Default.Save();
    }
}

Im Bereich Anwendung können die Einstellungen aus dem Programmcode lediglich gelesen werden (Schreibgeschützt), der obige Programmcode würde also einen Fehler erzeugen, da die Anwendungseinstellungen Schreibgeschützt sind.

Was aber, wenn man eine Einstellung die als Anwendungseinstellung definiert ist, durch Programmcode ändern und in die Config Datei zurückschreiben muss.

Dann kann man dazu folgende statische Methode verwenden:

private static void setAppSetting(string SettingdName, string SettingValue)
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.PreserveWhitespace = true;
    xmlDoc.Load(config.FilePath.Trim());
    XmlNode appSettingNode = xmlDoc.SelectSingleNode("configuration/applicationSettings");
    XmlNode settingNode = appSettingNode.SelectSingleNode(string.Format("//setting[@name='{0}']", SettingdName));
    XmlNode valueNode = settingNode.SelectSingleNode("value");
    valueNode.InnerText = SettingValue;
    xmlDoc.Save(config.FilePath.Trim());
}

Nachfolgend ein Beispiel wie man diese Methode im Programmcode einsetzt um eine “normerweise Schreibgeschütze” Einstellung zu ändern.

// auf normalem Weg lesend auf die Anwendungseinstellung zugreifen
if (Properties.Settings.Default.ApplicationVerladestelle == "DDC") 
{
	// Und hier mit Hilfe der setAppSetting Methode einen neuen Wert zuweisen und in die config Datei schreiben
    setAppSetting("ApplicationVerladestelle", "DCW");  
}

Settings.Default.Reload();  // Nicht vergessen, die aktuellen Werte noch mal zu laden

C# – DataGridView – Sichern und Wiederherstellen von Schreibgeschützten Spalten

Hintergrund

In einer Windows Form Applikation wird in einer Form ein DataGridView verwendet das je nach Bedarf Schreibgeschützt (Alle Spalten) oder zur Eingabe von Daten (nicht Schreibgeschützt) verwendet werden soll. Soweit würde die Anforderung auch kein Problem darstellen, wenn – aber dazu lest einfach den Rest des Beitrags.

Nun ist es aber so, dass auch in der Variante indem das DataGridView als Eingabe (also nicht Schreibgeschützt) verwendet wird, die eine oder andere Spalte des DataGridView sehr wohl (zur Zeit der Entwicklung, also nicht zur Laufzeit) auf Schreibgeschützt gesetzt wurden.

Eigentlich sollte das ganze kein Problem darstellen, also „Einfach sein“, wie es im Lied der FANTA4 beschrieben ist, aber wie geht es im Lied weiter; „is es aber nicht“, und genau so ist es auch in dem hier beschriebenen Fall.

Das Problem liegt daran, dass durch das setzen der ReadOnly Eigenschaft des DataGridView auf True das DataGridView „vergisst“ welche Spalten des DataGridView während der Entwicklungszeit auf ReadOnly gesetzt wurden.

Nachdem man während der Laufzeit die ReadOnly Eigenschaft des DataGridView einmal auf True und dann später wieder zurück auf False gesetzt hat, sind alle Spalten, auch diese die vorher ReadOnly waren plötzlich nicht mehr Schreibgeschützt.

Die Idee

Die Idee der nachfolgenden Lösung war schnell entstanden und wird im folgenden beschrieben.

Beim Start der Windows Form (am besten direkt im Konstruktor) muss man die Information der Schreibgeschützten Spalten sichern, und diese nachdem die ReadOnly Eigenschaft des DataGridView zurück auf False geändert wurde, einfach wieder auf die ursprünglichen Werte herstellen.

Die Lösung

Um die Information, welche Spalten beim Start der Windows Form Schreibgeschützt sind zu speichern, verwende ich ein typisiertes Array von int Werten um den Spalten Index der Schreibgeschützten Spalten zu sichern.

private List[int] saveReadOnlyColumn;

Die Logik zum Speichern der Informationen habe ich in eine eigene Methode (siehe nachfolgenden Code der Methode saveReadOnlyColumnInformation) ausgelagert, welche ich dann einfach am Ende des Konstruktor aufrufe.

private void saveReadOnlyColumnInformation()
{
    saveReadOnlyColumn = new List[int]();

    foreach (DataGridViewColumn o in dgVerladung.Columns)
    {
        if (o.ReadOnly)
        {
            saveReadOnlyColumn.Add(o.Index);
        }
    }
}

So nun haben wir die Informationen der Schreibgeschützten Spalten im typisierten Array für den späteren Gebrauch gespeichert.

Dann kümmern wir uns nun noch darum, diese gespeicherte Information immer dann wenn die ReadOnly Eigenschaft auf False gesetzt wurde, wieder auf die Startwerte zurücksetzen.

Hierzu können wir einfach den ReadOnlyChanged Event des DataGridView verwenden, welcher immer dann ausgelöst wird, wenn man im Code die ReadOnly Eigenschaft ändert.

Nachfolgend ist der Code dargestellt um die vorher gespeicherten Schreibgeschützten Spalten wieder herzustellen

private void dgVerladung_ReadOnlyChanged(object sender, EventArgs e)
{
    if (dgVerladung.ReadOnly == false)
    {
        foreach (int i in saveReadOnlyColumn)
        {
            dgVerladung.Columns[i].ReadOnly = true;
        }
    }
}

 

Der Vollständigkeit halber hier noch der Code des Konstruktor’s (Hier erklärt die Zeile 4) dargestellt.

public formPlanungen()
{
    InitializeComponent();
    saveReadOnlyColumnInformation();
    Application.Idle += new EventHandler(Application_Idle);
}

C# – DataGridView und Zwischenablage

Problemstellung

Die Daten eines DataGridView sollen über die Zwischenablage in verschiedene andere Anwendungen (unter anderem auch in Excel) kopiert und eingefügt werden können.

Hierbei soll es wahlweise Möglich sein, beim kopieren in die Zwischenablage, die Spaltenköpfe des DataGridView mit in die Zwischenablage zu kopieren. Außerdem soll es neben der Tastenkombination Strg + C auch über Programmcode (Button und oder Contextmenü) möglich sein, die Daten in die Zwischenablage zu kopieren.

Umsetzung – Teil 1 Spaltenüberschriften einschließen

Ob die Spaltenköpfe beim kopieren der DataGridView Daten mit einbezogen werden kann über die Eigenschaft ClipboardCopyMode des DataGridView gesteuert werden.

Die Eigenschaft kann auf folgende Werte gesetzt werden:

image

Der Standardwert lautet EnableWithoutHeaderText (Kopieren der markierten Daten ohne Spaltenköpfe).

Um sicherzustellen, dass auch die Spaltenköpfe mit in die Zwischenablage kopiert werden, muss der Wert EnableAlwaysIncludeHeaderText gesetzt werden.

DataGridView1.ClipboardCopyMode = EnableAlwaysIncludeHeaderText ;

Umsetzung – Teil 2 Programmatisches kopieren der Zwischenablage

Um per Programmcode die Daten (mit oder ohne Spaltenköpfe) in die Zwischenablage zu kann der folgende Code verwendet werden:

Clipboard.SetDataObject(DataGridView1.GetClipboardContent(), true);

C# – Gebundenes DataGridView – Die Suche geht weiter

Die Anforderung:

In einem gebundenen DataGridView, soll eine Suchfunktion implementiert werden, die es ermöglicht, dass man je nach angewählter Spalte innerhalb der Spalte nach einem in ein Suchfeld einzugebenden Text gesucht werden kann. Allerdings soll nicht nur auf genaue Übereinstimmung, sondern auch nur auf Teil -Übereinstimmung der dem Suchbegriff entsprechende erste Eintrag gefunden werden.

Die Problematik:

Grundsätzlich wird für die Umsetzung der Anforderung von der BindingSource eine Methode Find zur Verfügung gestellt.

Beispiel:

bool found = false;

int i = customerBindingSource.Find(dgCustomer.SortedColumn.DataPropertyName, txtSearch.Text);
if (i > -1)
{
    customerBindingSource.Position = i;
}
else
{
}

Soweit funktioniert das Prima, wenn der Suchtext genau mit dem Inhalt der Zelle entspricht.

Was aber wenn zum Beispiel in einer Spalte die Werte für den Name der erste Eintrag der mir M beginnt gefunden werden soll?

Dann funktioniert die Find Methode nicht, und leider bietet weder die BindingSource noch das DataGridView hierzu eine entsprechende Möglichkeit dies einfach per Methodenaufruf zu realisieren.

Die Eine Lösung:

Schauen wir uns doch mal an, was wir mit dem oben noch leeren Else Zweig anfangen können.

Das wir über die BindingSource nicht weiter kommen haben wir schon festgestellt, also müssen wir uns selbst etwas basteln.

Beispiel:

string searchField = dgCustomer.SortedColumn == null ? 
//Hier einfach den DataPropertyName des gewünschten Standardsuchfeldes wenn keine Spalte markiert ist
dgCustomer.SortedColumn.DataPropertyName;
string searchCellName = dgCustomer.SortedColumn == null ? 
//Hier einfach den Namen des gewünschten Standardsuchfeldes wenn keine Spalte markiert ist
dgCustomer.SortedColumn.Name;
bool found = false;

int i = customerBindingSource.Find(searchField, txtSearch.Text);
if (i > -1)
{
	customerBindingSource.Position = i;
}
else            
{
	foreach (DataGridViewRow row in dgCustomer.Rows)
	{
		if (row.Cells[searchCellName].Value == null)
		{
			continue;
		}

		if (row.Cells[searchCellName].Value.ToString().ToLower().StartsWith(txtSearch.Text.ToLower()))
		{
			i = customerBindingSource.Find(searchField, row.Cells[searchCellName].Value.ToString());
			if (i > -1)
			{
				customerBindingSource.Position = i;
				found = true;
				break;
			}
		}
	}
	if (!found )
	{
		string msg = string.Format(CultureInfo.CurrentUICulture, "{0} {1} konnte nicht gefunden werden", searchField, txtSearch.Text);
		MessageBox.Show(msg);                                                
	}
}

Ich Denke der Code ist selbsterklärend und bedarf keiner weiteren Erklärung.

Wenn ich mich damit täuschen sollte, dann einfach per Kommentar die Fragen stellen, oder noch besser gleich die Antworten geben :-).

C# .NET Interface Implementierung für 7-ZIP DLL Dateien

Das Open Source Projekt/Programm 7-ZIP erfreut sich großer Beliebtheit, und (fast) jeder wird das Programm (Die Windows Oberfläche) kennen.

Was aber wenn man gerne die Funktionalitäten von 7-ZIP in eigenen .NET Projekten (Managed Code) verwenden möchte.

Das ist nicht so einfach, da 7-ZIP in C++ (Unmanaged Code) geschrieben ist und eine direkte Verwendung der Methoden aus .NET Sprachen nicht möglich ist.

Heute bin ich aber auf einen interessanten Artikel gestoßen, der sich mit der Implementierung einer .NET Schnittstelle für die Nutzung der 7-ZIP DLL Bibliotheken beschäftigt.

In dem hier angesprochenen Artikel wird eine Schnittstellenimplementierung in C# vorgestellt.

http://www.codeproject.com/KB/DLL/cs_interface_7zip.aspx

Und wer 7-ZIP wirklich noch nicht kennen sollte, kann hier mehr darüber erfahren.

Windows Communication Foundation (WCF) – Welche Bindungen gibt es denn

Beim stöbern in den Tiefen der MSDN Dokumentationen bin ich mehr durch Zufall, als durch das Ergebnis einer Suchmaschine auf den Beitrag „Konfigurieren der vom System bereitgestellten Bindungen“ gestoßen.

Da ich bisher nichts (auf jeden Fall nichts auf Deutsch) finden konnte, wo die verschiedenen Bindungen die vom Framework zur Verfügung gestellt werden, kurz und prägnant aufgeführt und erläutert wurden, war ich gerade dabei und wollte das in einem eigenen Beitrag machen und da…

Ja da habe ich diesen Beitrag gefunden.

Hier nun kurz (sozusagen) als Suchmaschinen Hilfe für die MSDN Seite die verfügbaren Bindings kurz aufgelistet und dann der Link zu der Erläuterung auf MSDN.

Vom .NET Framework zur Verfügung gestellte Bindings für die Windows Communication Foundation

  • BasicHttpBinding
  • WSHttpBinding
  • WS2007HttpBinding
  • WSDualHttpBinding
  • WSFederationHttpBinding
  • WS2007FederationHttpBinding
  • NetTcpBinding
  • NetNamedPipeBinding
  • NetMsmqBinding
  • NetPeerTcpBinding
  • MsmqIntegrationBinding

Die MSDN Beschreibung lautet : Konfigurieren der vom System bereitgestellten Bindungen