[C#]: Methodeaufruf über XML steuern

JKruse

Grünschnabel
Guten Abend,

ich habe vor mein Menu in meiner Anwendung aus einer XML-Datei auszulesen und anschließend darzustellen. Soweit kein Problem.

Jetzt möchte ich aber zusätzlich in der XML-Datei hinterlegen, welche Methode aufgerufen werden soll bei einem Klick auf ein Menuitem.
Und da taucht meine große Frage auf, wie kann ich die "richtige" Methode auswählen?

In meine XML-Datei schreibe ich zum Beispiel exit.

In meiner Anwendung gibt es die Methode exit(). Kann man erreichen, dass genau diese Methode aufgerufen wird? Wenn ja wie geht so etwas?
Sinnvoll wäre auch eine Prüfung, ob es die angegebene Methode überhaupt gibt...

Vielen Dank vorab und noch einen schönen Abend!

Jens

PS: Ich entwickle in Visual Studio 2005
 
Hi,

ich habe dir ein Beispiel gezimmert, du sollstest dich über die Reflections in C# informieren ;)

C#:
using System;
using System.Reflection;

namespace Blubb
{
    class Program
    {
        static void Main()
        {
            MethodenSammlung meineMethoden = new MethodenSammlung();
            
            string methodenName = "exit";  //wird bei dir aus XML File geholt
            
            //jetzt methode aufrufen, deren Name in dem String steht
            MethodInfo info = meineMethoden.GetType().GetMethod(methodenName);
            try
            {
                info.Invoke(meineMethoden, null);
            }
            catch (NullReferenceException ex)
            {
                Console.WriteLine("Diese Methode gibts ja gar nich!");
            }
            catch (TargetParameterCountException ex)
            {
                Console.WriteLine("Die Methode die aufgerufen wurde, wurde mit zu viel oder zu wenig Parametern aufgerufen!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Es ist ein Fehler beim Aufruf der Methode \"{0}\" aufgetreten.\n" +
                                                "Genauere Problembeschreibung:\n\n{1}", methodenName, ex.Message));
            }
            Console.ReadKey();
           
        }
    }
    
    class MethodenSammlung
    {
     
        public void exit()
        {
            Console.WriteLine("Das Programm wird jetzt geschlossen!");
            //jetzt das Programm schließen
            //hmm... wie beendet man eigentlich eine Konsolen Anwendung :-D weiss jetzt nich
        }
    }
}

Lg, Yanick
 
Hallo!

hier mal ein Beispiel wie man Dynamisch ein Menu über eine XML Datei Konfigurieren kann:
C#:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Windows.Forms;

namespace De.Tutorials.DynamicMenuCreationExample.Util
{
    public class MenuBuilder
    {
        public static void BuildMenuFor(string menuDescriptorFilePath, MenuStrip menuStrip, Form form)
        {
            XmlDocument menuConfigrationDocument = new XmlDocument();
            menuConfigrationDocument.Load(menuDescriptorFilePath);
            XmlNodeList menuNodes = menuConfigrationDocument.GetElementsByTagName("menu");

            List<ToolStripItem> menus = new List<ToolStripItem>();

            foreach (XmlNode menuNode in menuNodes)
            {
                string menuName = menuNode.Attributes["id"].InnerText;
                string menuCaption = menuNode.Attributes["caption"].InnerText;
                ToolStripMenuItem toolStripMenu = new ToolStripMenuItem(menuCaption);
                toolStripMenu.Name = menuName;
                menus.Add(toolStripMenu);

                List<ToolStripItem> menuItems = new List<ToolStripItem>();

                foreach (XmlNode menuItemNode in menuNode.ChildNodes)
                {
                    string menuItemName = menuItemNode.Attributes["id"].InnerText;
                    string menuItemCaption = menuItemNode.Attributes["caption"].InnerText;
                    string menuItemActionClassName = menuItemNode.Attributes["action-class"].InnerText;
                    string menuItemActionMethodName = menuItemNode.Attributes["action-method"].InnerText;
                    ToolStripMenuItem menuItem = new ToolStripMenuItem(menuItemCaption);
                    menuItem.Name = menuItemName;
                    if (menuItemActionClassName.Length > 1)
                    {
                        object menuItemActionInstance = Activator.CreateInstance(Type.GetType(menuItemActionClassName), new object[] { menuItemName,form});
                        Delegate clickEventHandler = System.Delegate.CreateDelegate(typeof(EventHandler), menuItemActionInstance, menuItemActionMethodName, true);
                        menuItem.Click += (EventHandler)clickEventHandler;
                    }
   

                    menuItems.Add(menuItem);
                }

                toolStripMenu.DropDownItems.AddRange(
                    menuItems.ToArray()
                );
            }

            menuStrip.Items.AddRange(
                menus.ToArray()
                );
        }
    }

   
}

Menüs könnte man dann beispielsweise so deklarieren:
XML:
<?xml version="1.0" encoding="utf-8" ?>
<menus>
	<menu id="File" caption="File">
		<menuitem id="File.Foo" caption="Foo" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.FooMenuAction" action-method="run"/>
		<menuitem id="File.Bar" caption="Bar" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.BarMenuAction" action-method="run"/>
		<menuitem id="File.Exit" caption="Exit" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.ExitMenuAction" action-method="run"/>
	</menu>

	<menu id="ABC" caption="ABC">
		<menuitem id="ABC.Foo" caption="Foo" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.FooMenuAction" action-method="run"/>
		<menuitem id="ABC.Bar" caption="Bar" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.BarMenuAction" action-method="run"/>
		<menuitem id="ABC.Exit" caption="Exit" action-class="De.Tutorials.DynamicMenuCreationExample.Actions.ExitMenuAction" action-method="run"/>
	</menu>
</menus>

Beispielprojekt ist Angehängt.

Gruß Tom
 

Anhänge

  • 25401attachment.zip
    72,1 KB · Aufrufe: 66
Zuletzt bearbeitet von einem Moderator:
Hallo,

ich habe leider noch mal eine "Anfängerfrage"...
Ich stehe dabei etwas auf dem Schlauch...

Ich habe das erste Beispiel von Yanick ausprobiert und folgendermaßen erweitert:

Code:
class MethodenSammlung : Form1
{             
  public void exit()        
  {
    this.Exit();
  }
}

In meinem Formular (Form1) habe ich folgende Methode eingbaut:

Code:
public void Exit()
{
  this.Close();
}

Leider reagiert meine Anwendung nicht auf das this.Close()...

Habt ihr noch eine Idee?

Hintergrund ist, dass ich aus den aufzurufenden Methoden auf Objekte aus meinem Formular zu greifen möchte (ein paar Textboxen etc.). Deswegen wollte ich die Klasse MethodenSammlung als "Schnittstelle" nutzen, um meine vorhandenen Funktionen aufzurufen...

Würde mich über Eure neue Hilfe oder Anregung sehr freuen!

Viele Grüße
Jens
 
Hm...

Wenn du von einer Klasse erbst, ist es nicht die selbe Klasse, sondern die Klasse hat nur die selben Methoden etc.. ;)

Wenn du also this.Close() in einer geerbten Klasse aufrufst, bezieht sich das nur auf die aktuelle Klasse, was in deinem Fall nicht wirklich Sinn hat, da du in der Klasse MethodenSammlung das "geerbte" Formular gar nie aufrufst, egal, wieder zum Thema :):

Entweder du gibst der Methodensammlung die Form1 Klasse per Referenz weiter (beispielsweise über den Konstruktor: new MethodenSammlung(this); ), oder du tust die Methoden die du über XML Dateien aufrufen willst gleich in die Form1 ;)

Ob du sie in die Form1 Klasse packst oder nich das kommt darauf an, welche Methoden du alle Aufrufen willst, haben alle mit der Form1 Klasse zu tun, dann ist es logisch sie gleich da rein zu packen...

Lg, Yanick
 
Ja, sie haben alle mit meiner Form1 zu tun...

Ich habe es jetzt folgendermaßen umgebaut und jetzt klappt es wieder... ;)

Code:
...
string methodenName = "appExit";
MethodInfo info = this.GetType().GetMethod(methodenName);
try            
{                
  info.Invoke(this, null);            
}
...

Vielen Dank nochmal
 
Hallo,

ich bin leider auf ein Problem gestoßen... :(

Und zwar rufe ich wie oben beschrieben meine Methode auf, so weit so gut.
Meine Methode sieht aber so aus:
Code:
public void SendMail()
{
  FrmInternalContacts personal = new FrmInternalContacts();
  if (personal.ShowDialog() == DialogResult.OK)
  {
    ...
  }
}

Ich erhalte die letzte Fehlermeldung von Yanick mit folgendem Hinweis:
"Exception has been thrown by the target of an invocation."

Könnt ihr bitte noch einmal helfen?

Meine Anwendung scheint mit dem Aufruf des Dialoges nicht zurechtzukommen...

Könnt ihr mir sagen woran das liegt, und wie man das Problem beheben kann?

Viele Grüße
Jens
 
Das kann man mit dieser Fehlermeldung noch nicht sagen...

Gib bitte mal die InnerException aus!

Wenn du Visual Studio hast kannst du extrem super debbuggen, schau mal nach bei welchem Code Schnippsel genau die Exception geworfen wird, dann kann mal schon mal mehr sagen ;)

Lg, Yanick
 

Neue Beiträge

Zurück