DataGridView – Einträge manuell sortieren/verschieben

Heute stand ich vor der Aufgabe es zu ermöglichen, einzelne Zeilen eines DataGridViews manuell sortieren zu können bzw. die einzelnen Zeilen verschieben zu können. Da allerdings die Rows eines DataGridView Steuerelements schreibgeschützt sind habe ich mir einen kleinen Workaround geschrieben.

Beispiel für das Verschieben nach unten:

private void toolStripButtonStationStockDown_Click(object sender, EventArgs e)
{
	// Es darf nur eine Zeile selektiert sein
	if (this.dataGridViewStationen.SelectedRows.Count == 1)
	{
		// Wenn nach unten verschoben werden soll, darf das zu verschiebene Objekt nicht das Letzte sein
		if (this.dataGridViewStationen.SelectedRows[0].Index != (this.dataGridViewStationen.Rows.Count - 1))
		{
			// Gleichgroßes Array erstellen
			DataGridViewRow[] rows = new DataGridViewRow[this.dataGridViewStationen.Rows.Count];
			// Selektierten Index merken
			int selectedIndex = this.dataGridViewStationen.SelectedRows[0].Index;

			// Jede Zeile des Grids durchlaufen
			for (int i = 0; i < this.dataGridViewStationen.Rows.Count; i++)
			{
				// Ist diese Zeile vor der selektierten?
				if (i == selectedIndex + 1)
				{
					// Einen nach unten verschoben eintragen
					rows[i - 1] = this.dataGridViewStationen.Rows[i];
				}
				else if (i == selectedIndex) // Ist diese Zeile die selektierte?
				{
					// Einen nach oben verschoben eintragen
					rows[i + 1] = this.dataGridViewStationen.Rows[i];
				}
				else // Sonst
				{
					// An gleicher Stelle eintragen
					rows[i] = this.dataGridViewStationen.Rows[i];
				}
			}

			// Das Grid leeren
			this.dataGridViewStationen.Rows.Clear();

			// Das sortierte Array in das Grid schreiben
			for (int i = 0; i < rows.Length; i++)
			{
				this.dataGridViewStationen.Rows.Add(rows[i]);
			}

			// Selektion löschen
			this.dataGridViewStationen.ClearSelection();
			// Das verschobene Objekt an der neuen Stelle selektieren
			this.dataGridViewStationen.Rows[selectedIndex + 1].Selected = true;
		}
	}
}

Methode zum Aufruf von Mdi-Child Forms

Oft genug stand ich vor dem „Problem“ Fenster innerhalb eines Mdi-Containers korrekt zu öffnen. Mit ein wenig Hilfe aus dem Internet habe ich mir dann eine Methode geschrieben, die es mir erlaubt verschiedene Typen von Fenstern aufzurufen geregelt.
Die Methode überprüft zuerst (falls gewünscht), ob bereits ein Fenster vom gleichen Typ geöffnet ist. In diesem Fall wird der Fokus auf das Fenster gelegt. Andernfalls, wenn kein Fenster vom gleichen Typ existiert wird ein neues erstellt.

Methode:

/// <summary>
/// Open (new) Mdi Child
/// </summary>
/// <param name="mdiParent">Mdi Parent Form of the (new) Mdi Child</param>
/// <param name="typeOfChild">Type of the (new) Mdi Child</param>
/// <param name="windowstate">Windowstate to set for the (new) Mdi Child</param>
/// <param name="startposition">Startposition to set for the (new) Mdi Child</param>
/// <param name="allowMultipleInstances">Set true, if you want to create a new Form</param>
private void openMdiChild(Form mdiParent, Type typeOfChild, FormWindowState windowstate, FormStartPosition startposition, bool allowMultipleInstances)
{
	Form newForm = null;

	foreach (Form x in this.MdiChildren)
	{
		if (x.GetType() == typeOfChild)
		{
			newForm = x;
		}
	}

	if (newForm == null
		|| allowMultipleInstances)
	{
		Assembly ass = Assembly.GetAssembly(typeOfChild);
		newForm = (Form)ass.CreateInstance(typeOfChild.FullName);
	}

	newForm.MdiParent = mdiParent;
	newForm.StartPosition = startposition;
	newForm.Show();
	newForm.WindowState = windowstate; // Set WindowState after then .Show() to fix the MDI Container icon bug
	newForm.Focus();
}

Aufruf:

this.openMdiChild(this, typeof(FrmInetLoader), 
    FormWindowState.Maximized, FormStartPosition.CenterParent, true);