none
Array aus Form zurückgeben RRS feed

  • Frage

  • Hallo Forum,

    ich habe eine From1 und eine Form2.

    Aus der Form1 rufe ich die Form2 auf und mache diverse Abfragen und Einträge die in einem Array   "string[] Rueckgabe"  gespeichert werden.

    Wie kann ich das Array aus der Form2 an die Form1 zurückgeben ?

     


    Gruß Roland
    Dienstag, 12. April 2011 07:54

Antworten

Alle Antworten

  • Hallo Roland DE,

    warum implementierst du nicht eine Property oder eine getter-Methode in der Form2, die von Form1 aufgerufen wird, und die dir dann das Array zurückliefert? Oder bewegst du dich in einem asynchronen Kontext?

    Viele Grüße
    Holger M. Rößler

    Mittwoch, 13. April 2011 17:07
  • Hallo Holger,

    ich wollte eine universelle Suchmaske erstellen und dann die Einträge für den Filter zurückgeben. Die Suchmaske sollte aus n Forms aufrufbar sein.

    Hatt da an sowas wie mit dem "Return" gedacht.

     


    Gruß Roland
    Freitag, 15. April 2011 09:58
  • Hallo Roland,

    wenn ich dich richtig verstanden habe, ist dein Problem, dass jede Form eine Referenz auf die Suchmaske benötigt. Falls dem so ist kannst du je nach bedarf entweder ein Singleton oder eine Factory verwenden. Wenn alle Forms auf das gleiche Filterform Objekt zugreifen sollen, dann implementieren ein Singleton. Soll jedesmal eine neue Form erzeugt werden, dann implementiere eine Factory, die jedesmal ein neues Filterform Objekt erzeugt.

    Falls ich dich nicht richtig verstanden habe, dann präzisiere bitte dein Problem.

     

    Viele Grüße
    Holger M. Rößler

    Samstag, 16. April 2011 05:37
  • Hallo Holger,

    Danke für die Info. Singleton ist wohl genau das was ich benötige. Habe auch einiges im Internet gefunden. Dies bezieht sich aber alles eine Klasse. Muss allerdings gestehen das ich das auf mein Problem nicht so richtig übertragen kann.

    Ich verstehe das so :

    Bei Prg. Start müsste ich eine Klasse aufrufen. Wenn ich dann meine FormX egal aus welcher Form im Projekt benötige, müsste ich die FormX über die Klasse aufrufen.

    Wenn Du dazu etwas Code hättest wäre das super. Danke.


    Gruß Roland
    Dienstag, 19. April 2011 05:50
  • Hallo Roland,

    das Singleton-Pattern ist gar nicht so kompliziert. :o)

    Bei einem Singleton hält die Singletonklasse (deine FormX) eine statische Instanz von sich selbst. Der Konstruktor ist grundsätzlich private und von außen kannst du die Instanz nur über eine statische Methode der Singletonklasse holen. Somit hast du einen globalen Zugriffspunkt auf das Singelton.

    Ein Codebeispiel werde ich dir heute Abend  gerne mal reinstellen ;o)

    Viele Grüße
    Holger M. Rößler

    Dienstag, 19. April 2011 11:18
  • Hallo Roland,
    wie versprochen ein Codebeispiel für das Singleton Pattern:
    public class Singleton {
     private static Singleton _singleton;
    
     private Singleton() {
     //initialisierungen...
     }
    
     public static Singleton GetInstance() {
     if(Singleton._singleton == null) {
      Singleton._singleton = new Singleton();
     }
     return Singleton._singleton;
     }
    }
    
    Ich hoffe dieses Beispiel hilft dir, das Pattern zu verstehen und für dein Problem einzusetzen. Sollte es noch unklarheiten geben, so darfst du natürlich gerne nachfragen ;o)

    Viele Grüße
    Holger M. Rößler
     


    Dienstag, 19. April 2011 19:09
  • Hallo Holger,

    ich habe es jetzt hinbekommen, das meine FormX wenn sie bereits geöffnet ist nicht nochmal geöffnet wird, das löst aber leider nicht mein Problem.

    Wenn ich die FormX aus einer anderen Form öffne z.B. aus der Form1, und ich möchte Werte an die Form1 zurückgeben

    z.B.  Array   "string[] Rueckgabe"  dann muss ich die Form1 in der FormX eintragen. Das muss ich dann auch für die Form2, Form3, .. machen.

    Aber genau das möchte ich vermeiden. Ich suche eine Lösung wie ich in der FormX das   Array   "string[] Rueckgabe"  an jede aufrufende Form zurückgeben kann ohne diese einbinden zu müssen. Aber vielelicht sehe ich auch einfach die Lösung nicht.

    Kannst Du mir da nochmal helfen ?

     


    Gruß Roland
    Donnerstag, 21. April 2011 10:53
  • Hallo Roland,

    genau das musst du mit einem Singleton nicht. Wenn du deine FormX nach meinem Beispiel umgestaltet hast, so erhälst du immer die gleiche Instanz von deiner FormX ohne diese in einer anderen Form speichern zu müssen. Diese Referenz ist global und sie ist immer da. Wichtig ist, dass sowohl das Singleton und dessen Fabrikmethode statsich ist. Dann kannst über die Klasse auf die Fabrikmethode (in meinem Beispiel "GetInstance") zugreifen, ohne ein Objekt von FormX besitzen zu müssen.

    Hier mal ein komplexeres Beispiel:

    namespace SingletonExample {
      
      public interface IConfigurable {
       string[] Rueckgabe {
         get;
       }
      }
    
      public partial class FormX : Form, IConfigurable {
       private static FormX _singleton;
       
       private FormX() {
         InitializeComponent();
       }
    
       static FormX() {
         FormX._singleton = new FormX();
       }
    
       public string[] Rueckgabe {
         get { 
          //..do logic and return string[]
         }
       }
    
       public static IConfigurable GetInstance() {
         return FormX._singleton;
       }
      }
    
      public partial class Form1 : Form {
       public Form1() {
         string[] configForm1 = FormX.GetInstance().Rueckgabe;
       }
      }
    
      public partial class Form2 : Form {
       public Form2() {
         string[] configForm2 = FormX.GetInstance().Rueckgabe;
       }
      }
    
      public partial class Form3 : Form {
       public Form3() {
         string[] configForm3 = FormX.GetInstance().Rueckgabe;
       }
      }
    }
    

    Ich habe die von dir benötigte Logik mal in ein Interface ausgelagert um es dir etwas einfacher zu machen. Beachte bitte, dass das Singleton in einem statischen Konstruktor initialisiert und beachte bitte auch, dass die Fabrikmehtode als Rückgabetyp IConfigurable anstelle von FormX hat.

    Ich hoffe, das hilft dir weiter

    Viele Grüße
    Holger M. Rößler

    Donnerstag, 21. April 2011 17:11
  • Hallo Roland,

    Deine Beschreibung lässt mich vermuten, dass Du gar keinen Singletion willst, wie in Holger richtig beschrieben hat,
    sondern einen ganz normalen Dialog, wie z. B. den OpenFileDialog.

    Was Du Dir auch selbst machen kannst. Denn wenn Du ein Formular via ShowDialog aufrufst,
    so  kannst vorher und aber nach dem ShowDialog noch auf die Eigenschaften zugreifen.
    Über den DialogResult teilst Du dann Deinem aufrufendem Formular mit, ob gültige Daten vorliegen,
    oder ob der Anwender es sich anders überlegt hat und den Dialog via Abbrechen geschlossen hat.

    Ein einfaches Beispiel, wobei ich allerdings das String[] durch eine IList<String> ersetzt habe,
    denn auf Arrays sollte man weitgehen verzichten, da sie unhandlicher und im Zugriff unsicherer
    als eine Auflistung sind (muss es denn unbedingt ein String-Array sein, gilt der Rest aber weiterhin):

    Zunächst der das Formular FilterDialog, wo ich neben dem okButton und cancelButton noch zwei
    (sinnfreie) Textboxen für die Eingabe eingestellt habe, so dass man sieht was passiert:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
      public partial class FilterDialog : Form
      {
        public FilterDialog()
        {
          InitializeComponent();
        }
    
        private List<string> _filter = new List<string>();
        public IList<String> Filter
        {
          get { return this._filter.AsReadOnly(); }
          set
          {
            // Übergeben eines Filters
            this._filter.Clear();
            if (value != null)
            {
              this._filter.AddRange(value);
            }
          }
        }
    
        private void FilterDialog_Load(object sender, EventArgs e)
        {
          // Exemplarisch vorgebene Daten einer TextBox zuweisen
          if (this._filter.Count > 0)
            this.textBox1.Text = this._filter[0];
          if (this._filter.Count > 1)
            this.textBox2.Text = this._filter[1];
        }
    
    
        private void oKButton_Click(object sender, EventArgs e)
        {
          // Als AcceptButton festgelegt
          this._filter.Clear();
          // Exemplarisch zwei Werte
          this._filter.Add(this.textBox1.Text);
          this._filter.Add(this.textBox2.Text);
    
          this.DialogResult = DialogResult.OK;
        }
    
        private void cancelButton_Click(object sender, EventArgs e)
        {
          // Als CancelButton festgelegt, hier zur Verdeutlichung
          this.DialogResult = DialogResult.Cancel;
        }
      }
    }
    
    
    

    Und der Aufruf wäre dann (in einem beliebigen anderen Formular):

        void FilterAbrufen()
        {
          using (var dialog = new FilterDialog())
          {
            dialog.Filter = new List<string> { "Text 1", "Text 2" };
            if (dialog.ShowDialog(this) == DialogResult.OK)
            {
              Console.WriteLine("Filter:");
              foreach (var value in dialog.Filter)
                Console.WriteLine(value);
            }
            else
            {
              Console.WriteLine("Filter Dialog abgebrochen.");
            }
          }
        }
    
    
    
    Gruß Elmar

     

     

    Freitag, 22. April 2011 11:52
  • Hallo Holger,

    Danke für die weitere Info. Werde mir das nochmal genau ansehen.

    Hallo Elmar,

    an das habe ich auch schon gedacht und das würde sicherlich auch gehen, wenn ich das ganze nicht mit einem "MdiParent" benötigen würde. Da kommt leider eine Fehlermeldung das dies mit ShowDialog nicht zulässig ist.

      


    Gruß Roland
    Montag, 25. April 2011 19:57
  • Hallo Roland,

    Bei Dialogen funktioniert MdiParent nicht. Wozu brauchst Du das?

    Das MDI Konzept gilt heute als sehr veraltet, in neuen Anwendungen sollte man darauf verzichten.
    Sinnvoller ist das allgemein verbreitetere SDI-Konzept, was man z. B. mit in Windows Forms mit
    der DockPanelSuite erreichen kann.

    Und bei einer (allgemeinen) Such-/Filtermaske wählt man i. a. entweder einen modalen Dialog,
    oder beim Suchen auch unverankerte (floating) Fenster (siehe auch Visual Studio selbst).
    Als MDI Child würde man es kaum einbinden, da dabei der Bezug zum (verknüpften) Ursprungsfenster
    nicht erkennbar bleibt.

    Gruß Elmar

    Montag, 25. April 2011 21:42
  • Hallo Elmar,

    der von dir gepostete Link von der DockPanelSuite ist sehr interessant. Gibt es sowas auch für die WPF?

    Auf der Arbeit benutzen wir für das Docking Controls von Telerik. Diese sind aber leider nicht for free und für meine Privatprojekte (mit denen ich kein Geld verdiene) möchte ich nicht unbedingt 1.000 € ausgeben nur um meine Prism Module docken zu können.

    Vielen Dank und viele Grüße
    Holger M. Rößler

    Dienstag, 26. April 2011 05:11
  • Hallo Elmar,

    ich habe in meinem Projekt alle Aktionen und Fenster in einer "Anwendung" so wie in Excel oder Word auch. Machst Du weitere Tabellen in Excel auf, sind diese aller innerhalb des Fensters. Startest Du Excel nochmal, hat man wieder eine getrennte "Sitzung".

    Dies möchte ich auch in meiner Anwendung so steuern. Die Suchfenster sollten dann auch innerhalb der "Sitzung" sein und wenn es noch möglich ist am besten modal.

     


    Gruß Roland
    Dienstag, 26. April 2011 06:45
  • Hallo Holger,

    die DockPanelSuite ist bereit lange verfügbar.
    Für WPF gibt es AvalonDock,

    eine direkte Prism Integration gibt es AFAIK nicht,
    daran wird aber anderweitig gearbeitet, siehe Sofa

    Und auch: http://avalondock.codeplex.com/discussions/218475

    SharpDevelop z, B. hatte die DockPanelSute bis 3.0 verwendet,
    mit 4.0 ist man auf WPF gewechselt und verwendet AvalonDock.

    Gruß Elmar


    • Bearbeitet Elmar Boye Dienstag, 26. April 2011 09:06 Prism
    Dienstag, 26. April 2011 08:46
  • Hallo Roland,

    MDI und modal funktioniert nicht, da ein Dialog per Definitionem eine eigene
    Meldungschleife  verwendet, was die Weitergabe für MDI unterbricht.

    Die Integration von MDI und .NET orientiert sich an den älteren Windows Versionen (3.0/95).
    Für eine Nachbildung der Excel/Word Funktionalität ist sie ohne massiven Zusatzaufwand
    nicht ausreichend.

    Excel und Word arbeiten schon lange nicht mehr mit MDI, siehe z. B. Wikipedia dazu.
    Die Excel-Mappen verwenden ähnlich wie Visual Studio SDI/TDI (Single/Tabbed Document Interface)
    nur dass die Leiste dort unten angeordnet ist. Auch die gängigen Browser verwenden dies.

    Das mehrere Instanzen Feature wiederum ist eine indirekte Folge von, der Migration
    aber nicht zwingend notwendig (und für die meisten Anwender meiner Erfahrung nach eher verwirrend):

    Wenn Sie in Word 2000 und in höheren Versionen von Word ein weiteres Dokument erstellen
    oder öffnen, wird angezeigt, dass eine neue Instanz von Word ausgeführt wird

    Gruß Elmar

    Dienstag, 26. April 2011 09:04
  • Hallo Elmar,

    dank dir werden nun die Nutzer meiner "creationen" künftig  sich das UI so "hindocken" können, wie sie es gerne möchten *juhuuuuu* :o)


    Vielen Dank für den Link!!!


    Viele Grüße
    Holger M. Rößler

    Dienstag, 26. April 2011 17:16