Laden...

Windows-Form anhand eines String mit dem Klassennamen öffnen

Erstellt von Ramon vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.334 Views
R
Ramon Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren
Windows-Form anhand eines String mit dem Klassennamen öffnen

Hi @all!

Anhand eines Property würde ich gerne bei einem Button Click ein Formular öffnen


public class NeuerButton : Button
{
public NeuerButton()
{
}

void OpcButton_Click(object sender, EventArgs e)
{
if (p_fenster != string.Empty)
{
try
{
// ??? p_fenster entspricht einem System.windows.Forms.Form und sollte geöffnet werden ???
//Form win = p_fenster as Form;
//win.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

public string Fenster
{
get { return p_fenster; }
set { p_fenster = value; }
}

private string p_fenster = string.Empty;
}

Vielen Dank

Gruß Ramon

I
279 Beiträge seit 2008
vor 14 Jahren

So geht das aber nicht! Einen string kann man nicht in eine Form konvertieren!

3.825 Beiträge seit 2006
vor 14 Jahren

Ich mache das so :


if (dat == "winAdressen") { winAdressen dlg = new winAdressen(); dlg.ShowDialog(); }
if (dat == "winArtikel") { winArtikel dlg = new winArtikel(); dlg.ShowDialog(); }
if (dat == "winBelege") { winBelege dlg = new winBelege(); dlg.ShowDialog(); }
if (dat == "winWarengruppen") { winWarengruppen dlg = new winWarengruppen(); dlg.Show(); }
... es kommen noch 200 ähnliche Zeilen ;-)

Ob es besser geht weiss ich nicht.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

J
3.331 Beiträge seit 2006
vor 14 Jahren

Hallo Ramon,

// ??? p_fenster entspricht einem System.windows.Forms.Form und sollte geöffnet werden ???  
//Form win = p_fenster as Form;  
//win.Show();  

So ist das völlig unmöglich. Ein Formular ist ein Formular, also ein sehr komplexes Objekt. Ein String ist ein relativ einfaches Objekt. Es ist ausgeschlossen, dass aus einem String ein Form wird.

Du kannst allenfalls anhand eines Strings ein Objekt erzeugen, aber ob das bei einem Formular deinen Zwecken entspricht? Benutze einmal die Forumssuche z.B. nach aus einem string ein objekt erzeugen o.ä.; da gibt es den einen oder anderen Versuch. Aber das ist ziemlich komplex.

Oder suchst du nur nach Application.OpenForms["Ergänzungen"]?

Gruß Jürgen

// Na gut, Bernds Lösung geht zur Not.

2.223 Beiträge seit 2005
vor 14 Jahren

Hallo Ramon,

es wäre schön wenn Du ein wenig mehr darüber berichtigst was du genau machen möchtest.

Möglicherweise haben wir einen alternativweg für Dich.

Stichworte die Dir unter Umständen helfen könnten wäre ZB. Scripting oder Microkernel

Herzliche Grüße
Lars

3.825 Beiträge seit 2006
vor 14 Jahren

Mein Code wurde natürlich nicht manuell erstellt, sondern per Programm.

Am einfachsten gibt man in der Dos-Box ein :

dir *designer* /b >tmp.txt

Nach ein paar Suchen/Ersetzen und Kopieren ist der Sourcecode fertig.
Man muss nur beim Hinzufügen von Formularen entsprechende Zeilen hinzufügen.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

R
Ramon Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Hi @all!

Ich weiß, einen String kann man nicht in ein Form casten. Jedoch existieren diese Forms im Projekt alle. Leider ist es nicht möglich, dass ich eine if Abfrage mache, da das Programm nicht weiß welche Forms existieren (oder zumindest nur indirekt). Um etwas Licht in die Sache zu bringen um was es eigentlich geht:

  1. Ich habe einen neuen Button erzeugt, abgeleitet von Button. Dieser Button hat ein Property "Fenster".

[EditorAttribute(typeof(SelectForm), typeof(System.Drawing.Design.UITypeEditor))]
public string Fenster
{
get { return p_fenster; }
set { p_fenster = value; }
}

Ursprünglich wollte ich statt public string Fenster eigentlich public Form Fenster verwenden. Da jedoch in diesem Fall nur das aktuelle Form angezeigt wird, ist das nicht wirklich sinnvoll. Es sollten nämlich alle im Projekt enthaltenen Forms angezeigt und ausgewählt werden können.

  1. Damit ich jetzt ein modales Fenster in der IDE anzeigen kann, welches dann alle Forms des aktuellen Projekts abfragt, habe ich den UITypeEditor abgeleitet

internal class SelectForm : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}

public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
FormAuswahl form = new FormAuswahl();
form.ShowDialog();

return form.Fenster;
}
}

Das funktioniert auch schon perfekt. Nur leider weiß ich jetzt noch nicht, wie ich anhand eines Strings das richtige Form auswähle. Stehe da irgendwie auf der Leitung.
Vielen Dank

Gruß Ramon

5.299 Beiträge seit 2008
vor 14 Jahren

der Button bräuchte als Property den Typ System.Type. Dann kann er jeden Typ erstellen, und wenns ein Form ist, halt auch anzeigen.

Ist jetzt die Frage, ob dein AuswahlForm auch einen Type returnen kann, statt des Strings.

PS: Mit der Activator-Klasse kann man aus einem Type eine Objekt-Instanz erstellen.

Der frühe Apfel fängt den Wurm.

R
Ramon Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

@ErfinderDesRades

Der Ansatz ist sehr gut. Leider hab ich für den Abruf der Projektdaten (Forms) die ROT (Running Object Table) benutzt. Somit ist es wieder schwieriger von COM zu .NET Types zu kommen. Muss mich vielleicht mal umschauen ob es statt ROT noch etwas anderes gibt.

344 Beiträge seit 2006
vor 14 Jahren

Hallo

So eine spontane Idee.
Den Klassennamen des Forms in der Form.Tag Eigenschaft speichern. Dann die offenen Forms durchlaufen, und wenn frm.Tag == "tagname" dann ist es das gesuchte Form.

Gruss Lothi

R
Ramon Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Hi @all!

War ja dann eigentlich eh ganz einfach 😃. Falls die Lösung noch jemand benötigt:

  1. Anhand der ROT (Running Object Table) das aktuelle Visual Studio Projekt und damit das aktuelle Projektverzeichnis herausfinden.
  2. Alle Files in dem Verzeichnis durchgehen und Namespace und Classname herauskitzeln.
  3. Form mit ListView darstellen und für den User auswählbar machen
  4. Property als string im Format namespace.classname (Bsp: "Test1.Class1";) für den neuen Button hinterlegen
  5. Bei einem Click auf den Button die ausgeführte Assembly ermitteln und mit Hilfe von Activator die Instanz erstellen

if (p_fenster != null)
{
try
{
Type i_type = System.Reflection.Assembly.GetEntryAssembly().GetType(p_fenster); // p_fenster in form von "Test1.Class1" (namespace.classname)

if (i_type != null)
{
Form i_form = (Form)Activator.CreateInstance(i_type);
i_form.Show();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

5.299 Beiträge seit 2008
vor 14 Jahren

Hi!

Jo, da denkich, das wäre doch ein recht nettes Snippet für die myCharp-Snippet-Sammlung - haste nicht Lust, einen kleinen, lauffähigen Zip dort einzustellen?

(und ich würde das mit dem ROT lernen können)

Der frühe Apfel fängt den Wurm.