ip2long – long2ip – C# Ersatz für PHP Funktionen

In einem Projekt musste ich mit Daten arbeiten welche durch eine PHP Anwendung erstellt wurden (werden).

Unter anderem wird dabei die IP Adresse des Besuchers in einer Datenbank gespeichert.

Bei der Speicherung der IP wird diese aber nicht als String sondern als long Wert gespeichert.

PHP bietet hierzu folgende Funktionen an:

  • ip2long
  • long2ip

Obwohl, oder gerade weil ich kein PHP Guru bin, stellt sich mir nun die Aufgabe diese Long Werte wieder in IP Adressen zurück zu übersetzen.

Und eben nicht mit PHP sondern mit C#.

Hierzu habe ich mir 2 statische Methoden in einer IP-Helper Klasse erstellt die genau diese Funktionalität der PHP Funktionen in C# nachempfindet.

Nachfolgend meine beiden C# Methoden:

public static long ip2long(string ipAddress)
{
    System.Net.IPAddress ip;
    
    if (System.Net.IPAddress.TryParse(ipAddress,out ip))
    {                
            return (((long) ip.GetAddressBytes()[0] << 24) | (ip.GetAddressBytes()[1] << 16) |
                    (ip.GetAddressBytes()[2] << 8) | ip.GetAddressBytes()[3]);
    }
    return -1;
}

public static string long2ip(long ipAddress)
{
    System.Net.IPAddress ip;
    if (System.Net.IPAddress.TryParse(ipAddress.ToString(), out ip))
    {
        return ip.ToString();
    }
    return "";
}

Eventuell braucht das ja auch noch jemand anderes !

DataGridView – Fehlender CheckedChanged Event für Checkboxen – Winforms – C#

Wer sich mit WinForms Entwicklung beschäftigt wird wohl auch mit dem DataGridView Control arbeiten.

Wenn man nun für die Spalte ein Checkbox Control “DataGridViewCheckBoxColumn” verwendet kommt es häufig vor, dass man auch auf das CheckedChanged Ereignis reagieren möchte.

Leider gibt es mit dem DataGridView Control nicht direkt die Möglichkeit einen solchen Event zu nutzen.

Außerdem wird bei der Verwendung von Datengebundenen Informationen an das DataGridView Control erst nach verlassen der aktiven Zelle die Dirty Eigenschaft der Zelle gesetzt, so dass dies nicht mehr zulässt direkt auf Änderung der Checked Eigenschaft zu reagieren.

Es gibt aber, wie fast immer, Abhilfe für das Problem.

Um  bereits vor dem Verlassen der Zelle, die Änderung der Checked Eigenschaft auszuwerten, kann man dem DataGridView den Event CurrentCellDirtyStateChanged hinzufügen und in diesem Event den nachfolgend dargestellten Code hinzufügen:

Als Einfaches Beispiel (Allgemeingültig):

private void dgVerladung_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (((DataGridView)sender).CurrentCell.OwningColumn is DataGridViewCheckBoxColumn)
    {
        ((DataGridView)sender).CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

Ein etwas komplexeres Beispiel (nur als Beispiel):

private void dgWorkTime_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgWorkTime.CurrentCell.OwningColumn.Name == disabledDataGridViewCheckBoxColumn.Name)
    {
        dgWorkTime.CommitEdit(DataGridViewDataErrorContexts.Commit);
        Day meinTag = (Day)dgWorkTime.CurrentCell.OwningRow.Cells[dayEnumDataGridViewTextBoxColumn.Name].Value;
        bool disabled = (bool)dgWorkTime.CurrentCell.Value;
        dgWorkTime.CurrentRow.Cells[startWorkingTimeDataGridViewTextBoxColumn.Name].ReadOnly = disabled;
        dgWorkTime.CurrentRow.Cells[endWorkingTimeDataGridViewTextBoxColumn.Name].ReadOnly = disabled;
        if (disabled)
        {
            dgWorkTime.CurrentRow.Cells[wochentagDataGridViewTextBoxColumn.Name].Style.BackColor =
                Properties.Settings.Default.WorkingTimeDisabledColor;
            dgWorkTime.CurrentRow.Cells[disabledDataGridViewCheckBoxColumn.Name].Style.BackColor =
                Properties.Settings.Default.WorkingTimeDisabledColor;
            dgWorkTime.CurrentRow.Cells[startWorkingTimeDataGridViewTextBoxColumn.Name].Style.BackColor =
                Properties.Settings.Default.WorkingTimeDisabledColor;
            dgWorkTime.CurrentRow.Cells[endWorkingTimeDataGridViewTextBoxColumn.Name].Style.BackColor =
                Properties.Settings.Default.WorkingTimeDisabledColor;
        }
        else
        {
            dgWorkTime.CurrentRow.Cells[wochentagDataGridViewTextBoxColumn.Name].Style.BackColor =
                dgWorkTime.CurrentRow.Cells[dayEnumDataGridViewTextBoxColumn.Name].Style.BackColor;
            dgWorkTime.CurrentRow.Cells[disabledDataGridViewCheckBoxColumn.Name].Style.BackColor =
                dgWorkTime.CurrentRow.Cells[dayEnumDataGridViewTextBoxColumn.Name].Style.BackColor;
            dgWorkTime.CurrentRow.Cells[startWorkingTimeDataGridViewTextBoxColumn.Name].Style.BackColor =
                dgWorkTime.CurrentRow.Cells[dayEnumDataGridViewTextBoxColumn.Name].Style.BackColor;
            dgWorkTime.CurrentRow.Cells[endWorkingTimeDataGridViewTextBoxColumn.Name].Style.BackColor =
                dgWorkTime.CurrentRow.Cells[dayEnumDataGridViewTextBoxColumn.Name].Style.BackColor;

        }

    }

Lambda Expressions – C#

Lambda Expressions in C# umfassen sowohl Ausdrücke (expressions) als auch Anweisung’s Blöcke (statement blocks).

Egal welche Art von Lambda Expressions verwendet werden, der Lambda Operator => wird jeweils dazu verwendet um die Expression zu beschreiben.

Was ist der Unterschied zwischen einem Ausdruck und einem Anweisung’s Block.

Exemplarische Lambda Expression Ausdrücke
x => x * 5

(int x) => x * 5

o => o.FirstName == "Peter"

(Order o) => o.FirstName == "Peter"

Exemplarische Lambda Expression Anweisung’s Blöcke

y => {return 5 * x)

Wo überall setzt man Lambda Expressions ein?

Ein großes Einsatzgebiet von Lambda Expressions sind zum Beispiel zusammen mit den ebenfalls in C# 3.0 neuen Extension Methods.

DayOfWeek To Day – C#

Da sich Microsoft nicht einig ist wie man die Tage einer Woche in einer Aufzählung hinterlegt, muss man damit klarkommen, dass es verschiedene Auflistungen in verschiedenen Namensräumen gibt.

In einem meiner Projekte war ich nun auch damit konfrontiert, dass ich mit den beiden Aufzählungen:

  • DayOfWeek aus dem Namensraum System

und

  • Day aus dem Namensraum System.Windows.Forms

gleichzeitig zu tun hatte.

Dabei ergab sich die Notwendigkeit dass DayOfWeek in Day umwandeln musste.

Nachfolgend nun eine kleine Methode die aus DayOfWeek ein Day zurückgibt.

public static Day DayOfWeekToDay(DayOfWeek dow)
{
    return (Day)Enum.Parse(typeof(Day), dow.ToString());
}

Erster Tag eines Monats – C#

Auch wenn es auf den ersten Blick absurd erscheint, dass man eine Funktion benötigt um den ersten Tag eines Monats zu ermitteln, aber es gibt Situationen in welchen man Datumsbereiche bestimmen möchte in denen man aus einem beliebigen Datum den ersten Tag eines Monats ermitteln muss.

Nachfolgend eine C# Methode die genau dies macht:

public static DateTime FirstDateOfTheMonth(DateTime date)
{
    return date.AddDays(-(date.Day - 1));
}

DotNetNuke und NET Framework 2.0 SP 1

Ich möchte in diesem Beitrag nicht ergründen, ob das von mir geschilderte Problem durch DotNetNuke oder den Service Pack 1 für das NET Framework 2.0 verursacht wird. Fakt ist auf jeden Fall das dieses Problem in der von mir beschriebenen Konstellation auftritt.

Das Problem stellte sich bei mir wie folgt dar (Windows XP Rechner):

  • Source Version von DotNetNuke 4.08.00 entpackt (C:\DNN_4_8_0).
  • development.config nach web.config umbenannt (Alle Einstellungen belassen)
  • Virtuelles Verzeichnis (dnn488) auf Localhost angelegt.
  • Verzeichnisrechte (C:\DNN_4_8_0) für ASPNET Benutzer (ALLE Rechte) gesetzt.
  • Internet Explorer, URL (localhost/dnn488) des virtuellen Verzeichnis eingegeben und aufgerufen.
  • Installationswizzard mit Auto ausgeführt.
  • Installation ist einwandfrei durchgelaufen.
  • Nun Link zum Start des Portal aufgerufen –> Nix.

Im IE einfach nur warten…

Mit Firefox bekommt man eine Meldung dass man sich in einer Endlosschleife befindet und man nie ein Ergebnis erzielen wird

Nach einigen Recherchen und Versuchen (wenn man anstelle der development.config die release.config verwendet geht es übrigens) war klar wo das Problem liegt.

<trust level="Medium" originUrl=".*" />

Der oben dargestellt Eintrag für dazu dass man in ein ewiges Redirect Status Codes 302 gerät.

Auf einem Entwicklungsrechner kann man einfach diese Zeile in der web.config auskommentieren und schon funktioniert der Aufruf des Portals wie erwartet.


Das Problem hat übrigens nichts mit der verwendeten DotNetNuke Version 4.8.0 zu tun, es tritt sowohl bei den neuen Versionen 4.8.1 und 4.8.2 als auch bei früheren Versionen 4.5.3 und 4.6.2 auf.

Alle Controls einer Form auf Readonly setzen – Winforms – C#

Ein einzelnes Control auf Readonly zu setzen ist einfach, aber was ist wenn man alle Controls einer Winforms Anwendung auf Readonly setzen möchte. Und ich meine wirklich auf Readonly nicht auf Enabled indem man ein Panel als Container der Controls verwendet und dann die Panel Eigenschaft Enabled auf false setzt.

Zu diesem Zweck habe ich mir eine kleine Routine erstellt, welche Rekursiv alle Controls (die ich möchte) einer ControlCollection auf Readonly setzt.

Hier nun die Methode setReadOnly:

private void setReadOnly(Control.ControlCollection Controls)
{
    foreach (Control control in Controls)
    {
        if (control is TextBox)
        {
            ((TextBox)control).ReadOnly = true;

        }
        if (control is ComboBox)
        {
            ((ComboBox)control).Enabled = false;
        }
        if (control is DateTimePicker)
        {
            ((DateTimePicker)control).Enabled = false;
        }

        if (control.Controls.Count &gt; 0)
        {
            setReadOnly(control.Controls);
        }
    }

}

Controls versus Components

In Gesprächen mit Entwicklern taucht immer wieder die Frage auf was Controls von Components unterscheidet.

 

Die Kurzbeschreibung hierzu lautet:

 

Im Gegensatz zu Controls haben Components keine Visuellen Eigenschaften.

Es wird also nichts auf einer Form angezeigt.

Das was Components mit Controls gemeinsam haben, ist, dass man Sie zu einer Form hinzufügen kann und dass sie beide zur Design Time konfiguriert werden können.