[.NET] Eigenen Datentyp in settings.settings anzeigen und verwenden

Oft kommt es vor, dass man in einem Projekt Programmeinstellungen in der settings.settings speichern möchte. Standardmäßig sind die von .NET mitgelieferten Datentypen verfügbar, jedoch sind eigene Datentypen nicht aufgelistet. Um diese verwenden zu können, sind folgende Bedingungen zu erfüllen:

  • der enstprechende Datentyp muss public sein,
  • er muss einen Standardkonstruktor haben,
  • er muss serialisierbar sein,
  • das Projekt muss einmal durchcompiliert worden sein (Projekt->Neu erstellen), damit die ganzen Abhängigkeiten im Projekt geklärt sind

Um in einer den Settings-Property Zugriff auf den eigenen Datentyp zu haben muss man bei der Typauswahl auf die Combobox (Typ) klicken, und dann “Durchsuchen…” wählen. Ist der Typ oben im Fenster in der Baumauswahl nicht gelistet, muss er unten im Feld “Ausgewählter Typ” manuell mit vollem Namespace eingetragen werden (z.B. System.IO.SuperNet.ConnectionType). Danach mit “OK” bestätigen. Nun erscheint wie von Zauberhand der gewählte eigene Datentyp in der ComboBox für die Typauswahl.

[C#] Window maximized event abfangen

Variante 1:

private void Form1_SizeChanged(object sender, EventArgs e)
{
	if (this.WindowState == FormWindowState.Maximized)
	{
		...
	}
}

Variante 2:

protected override void WndProc(ref Message m)
{
	if ((UInt32)m.Msg == Constant.WM_SYSCOMMAND)
	{
		switch ((UInt32)m.WParam)
		{
			case Constant.SC_MAXIMIZE:
                break;
			case Constant.SC_RESTORE:
                break;
			default:
				break;
		}
	}
	base.WndProc(ref m);
}

[C#] DataGridView Drag & Drop in eine Zeile (Row)

Im Beispiel liegen zwei DataGridViews auf einem Formular: gvSource und gvTarget. Die gewählte Zeile aus gvSource wird per Drag & Drop in gvTarget gezogen.

// Eigenschaften die gesetzt werden müssen
gvSource.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.AllowDrop = true;

// wenn im gvSource ein oder mehrere Zeilen markiert und der linke Mausbutton gedrückt gehalten wird
private void gvSource_CellMouseDown(object sender, MouseEventArgs e)
{
    // nur DragDrop initiieren, wenn Elemente aus dem Zellenbereich gewählt,
    // sonst gibt es Probleme beim Einstellen der Spaltenbreite per Maus
    if (e.RowIndex != -1)
    {
        if (gvSource.SelectedRows.Count > 0)
        {
            DragDropEffects dropEffect = gvSource.DoDragDrop(gvSource.SelectedRows, DragDropEffects.Copy);
        }
    }
}

// wenn die Maus mit den Objekten über gvTarget ist
private void gvTarget_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    DataGridViewSelectedRowCollection rows = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows != null)
    {
        e.Effect = DragDropEffects.Copy;
    }
}

// Objekte aus gvSource in gvTarget einfügen, Doppelungen vermeiden
private void gvTarget_DragDrop(object sender, DragEventArgs e)
{
	DataGridViewSelectedRowCollection rows_source = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

	if (rows_source != null)
	{
		Point p = gvTarget.PointToClient(new Point(e.X, e.Y));
		DataGridView.HitTestInfo info = gvTarget.HitTest(p.X, p.Y);

		if (info.RowIndex != -1 && info.ColumnIndex != -1)
		{
			foreach (DataGridViewRow rs in rows_source)
			{
				bool bFound = false;

				// prüfen, ob schon in der Liste
				foreach (DataGridViewRow row_target in gvTarget.Rows)
				{
					// Vergleich von Spalte mit Index 0, wenn gleich, dann schon vorhanden
					if (rs.Cells[0].Value.ToString() == row_target.Cells[0].Value.ToString())
					{
						bFound = true;
						break;
					}
				}

				// wenn noch nicht vorhanden, dann einfügen
				if (bFound == false)
				{
					DataGridViewRow rnew = new DataGridViewRow();
					rnew.CreateCells(gvTarget);

					// Indexe beachten, Spaltenanordnung von gvSource muss
					// nicht der von gvTarget entsprechen
					rnew.Cells[0].Value = rs.Cells[1].Value.ToString();
					rnew.Cells[1].Value = rs.Cells[2].Value.ToString();
					rnew.Cells[2].Value = rs.Cells[3].Value.ToString();

					gvTarget.Rows.Add(rnew);
				}
			}
		}
	}
}

[C#] JSON serialisieren/deserialisieren

JSON-Daten liegen in einem eigenen Format vor. Um dieses Datenformat in C# abzubilden benötigt man zuerst eine oder mehrere Klassen. Der Einfachheit halber kann man sich auf der Seite http://json2csharp.com/ aus dem JSON-Datenformat automatisiert C#-Klassen bauen lassen.

Als Beispiel dient folgende JSON-Datei:

{
"SerialNumber": "05857628",
"DateTime": "1415783932",
"Meters": [{
"InputNumber": "1",
"Name": "HZ Wirkleistung BZ 90612021",
"Type": "Electricity",
"Value": 2092224.000,
"Unit": "Wirkleistung"
},
{
"InputNumber": "2",
"Name": "HZ Blindleistung BZ 90612021",
"Type": "Electricity",
"Value": 2093763.500,
"Unit": "Blindleistung"
},
]
}

Die zugehörigen C#-Klassen sehen wie folgt aus:

using System.Collections.Generic;
using System.Runtime.Serialization;

namespace JSONTest
{
    [DataContract]
    public class Meter
    {
        [DataMember]
        public string InputNumber { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Type { get; set; }
        [DataMember]
        public double? Value { get; set; }
        [DataMember]
        public string Unit { get; set; }
    }

    [DataContract]
    public class Meter_List
    {
        [DataMember]
        public string SerialNumber { get; set; }
        [DataMember]
        public string DateTime { get; set; }
        [DataMember]
        public List<Meter-> Meters { get; set; }
    }
}

Im Code greift man nun folgendermaßen auf die Daten zu:

// im Projektbaum Verweis hinzufügen: System.Runtime.Serialization
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

private void btnGetJSON_Click(object sender, EventArgs e)
{
	// JSON-File von URL holen
	string contents = new System.Net.WebClient().DownloadString("www.datenquelle.de");

	// JSON deserialisieren
	DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Meter_List));
	MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(contents));
	Meter_List obj = (Meter_List)ser.ReadObject(stream);

	// Daten ausgeben
	Console.WriteLine(obj.SerialNumber);
	Console.WriteLine(obj.Meters.Count);
	Console.WriteLine(obj.Meters[0].Name);
}

Quelle: Serializing and Deserializing JSON in C#

[C#] DataGridView Drag & Drop (MultiSelect)

Im Beispiel liegen zwei DataGridViews auf einem Formular: gvSource und gvTarget. Die gewählten Zeilen (MultiSelect ist möglich) aus gvSource werden per Drag & Drop in gvTarget gezogen. Vorrausetzung ist hierbei, dass in beiden DataGridViews die gleichen Spalten vorhanden sind.

// Eigenschaften die gesetzt werden müssen
gvSource.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvSource.MultiSelect = true;
gvTarget.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.AllowDrop = true;

// wenn im gvSource ein oder mehrere Zeilen markiert und der linke Mausbutton gedrückt gehalten wird
private void gvSource_CellMouseDown(object sender, MouseEventArgs e)
{
    // nur DragDrop initiieren, wenn Elemente aus dem Zellenbereich gewählt,
    // sonst gibt es Probleme beim Einstellen der Spaltenbreite per Maus
    if (e.RowIndex != -1)
    {
        if (gvSource.SelectedRows.Count -> 0)
        {
            DragDropEffects dropEffect = gvSource.DoDragDrop(gvSource.SelectedRows, DragDropEffects.Copy);
        }
    }
}

// wenn die Maus mit den Objekten über gvTarget ist
private void gvTarget_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    DataGridViewSelectedRowCollection rows = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows != null)
    {
        e.Effect = DragDropEffects.Copy;
    }
}

// Objekte aus gvSource in gvTarget einfügen, Doppelungen vermeiden
private void gvTarget_DragDrop(object sender, DragEventArgs e)
{
    DataGridViewSelectedRowCollection rows_source = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows_source != null)
    {
        foreach (DataGridViewRow rs in rows_source)
        {
            bool bFound = false;

            // prüfen, ob schon in der Liste
            foreach (DataGridViewRow row_target in gvTarget.Rows)
            {
                // Vergleich von Spalte mit Index 0, wenn gleich, dann schon vorhanden
                if (rs.Cells[0].Value.ToString() == row_target.Cells[0].Value.ToString())
                {
                    bFound = true;
                    break;
                }
            }

            // wenn noch nicht vorhanden, dann einfügen
            if (bFound == false)
            {
                DataGridViewRow rnew = new DataGridViewRow();
                rnew.CreateCells(gvTarget);

                rnew.Cells[0].Value = rs.Cells[0].Value.ToString();
                rnew.Cells[1].Value = rs.Cells[1].Value.ToString();
                rnew.Cells[2].Value = rs.Cells[2].Value.ToString();

                gvTarget.Rows.Add(rnew);
            }
        }
    }
}