Datei per Drag&Drop von .NET Anwendung in Windows Explorer

In Bezug auf einen vorherigen Artikel nun einmal die andere Richtung. Mit dem folgenden Code kann eine Datei per Drag&Drop in z.B. den Windows Explorer kopiert werden.

private void myControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
	System.Collections.Specialized.StringCollection filePath = new System.Collections.Specialized.StringCollection();
	filePath.Add(@"C:\Testdatei.txt");
	DataObject dataObject = new DataObject();
	dataObject.SetFileDropList(filePath);

	this.myControl.DoDragDrop(dataObject, DragDropEffects.Copy);
}

Forms Application innerhalb des Konstruktors beenden

Innerhalb einer Anwendung habe ich mehrere Überprüfungen im Konstruktor hinterlegt, die dazu führen können, dass die Anwendung nicht geöffnet werden soll. Allerdings bringt es wenig, wenn man innerhalb des Konstruktor Application.Exit() aufruft. Application.Exit() durchläuft alle z.Z. geöffneten Forms und löst für jedes das FormClosing-Ereignis aus. Anschließend ruft es ThreadContext.ExitApplication() auf, was für die Forms des aktuellen Threads Dispose() aufruft. Das Problem dabei ist nur, dass das Hauptformular im eigenen Konstruktor noch gar kein Handle hat und somit kann Control.Dispose() nicht aufgerufen werden.

Deshalb verwendung ich zum Beenden der Anwendung folgende Methode:

Environment.Exit(0);

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);