Announcement

Collapse
No announcement yet.

(WPF) Datenaustausch zwischen zwei Fenstern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • (WPF) Datenaustausch zwischen zwei Fenstern

    Hallo,

    Ich schreibe gerade ein Projekt in WPF und es wäre sehr gut wenn ich Daten zwischen zwei Fenstern der Anwendung Übertragen kann.

    Jedoch will es mir nicht gelingen dies zu bewerkstelligen. Könnt ihr mir vllt. einen Denkanstoß geben?

    Mit freundlichen Grüßen
    Promos

  • #2
    Hallo,

    für den Datenaustausch zwischen Fenstern gibt es verschiedenste Konzepte. Die "sauberste" Lösungen werden mit MVP und Abwandlungen erreicht.

    Um aber nicht auf alle Details eingehen zu müssen - da kannst du sich selber in diese Thematik mal einlesen - soll hier nur verkürzt der Gedanke dargestellt werden.

    Anstatt Fenster 1 (=: F1) direkt mit Fenster 2 (=: F2) kommunizieren zu lassen sollte die Kommunikation über eine 3. Klasse (=: C) erfolgen. D.h.
    F1 <-> C <-> F2

    Somit ist das Ganze sauber getrennt denn F1 kennt F2 nicht und vice versa. Nur C kennt F1 und F2.

    Für die eigentliche Kommunikation gibt es wiederum verschiedenste Möglichkeiten. Momentan bevorzuge ich eine Variante bei der mittels Events die einzelnen Komponenten kommunizieren -> Stichwort: Event based Components - EBC.

    Das hört sich aufwändiger an als es ist und langfristig lohnt sich das auf jeden Fall.


    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Danke gfoidl,

      Ich habe mir deinen Link durchgelesen, aber verstehe leider nicht ganz in welcher Datei der gute Herr seine Calculator Class definiert.

      Und leider weiß ich dadurch auch nicht wie genau ich meine Stringübergage realisieren kann. Klar weiß ich jetzt das ich mir dafür eine Methode schreiben sollte, nur leider noch nicht ob ich sie in den Code von Fenster 2 oder Fenster1 schreiben muss.

      MfG
      Promos

      Comment


      • #4
        [highlight=c#]
        public partial class Form1 : Form
        {
        public Form1()
        {
        InitializeComponent();
        }

        public Action<String> SelectionChanged;

        // Wird aufgerufen wenn sich der gewünschte String im Programm ändert
        private void ChangeSelection(String changedString)
        {
        SelectionChanged(changedString);
        }

        private void button1_Click(object sender, EventArgs e)
        {
        ChangeSelection(textBox1.Text);
        }
        }

        public partial class Form2 : Form
        {
        public Form2()
        {
        InitializeComponent();
        }

        public void ChangeString(String changedString)
        {
        //mache was mit geändertem String
        label1.Text = changedString;
        }
        }

        static void Main()
        {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(fals e);

        Form1 form1 = new Form1();
        Form2 form2 = new Form2();

        form1.SelectionChanged = form2.ChangeString;
        form1.Show();
        form2.Show();

        Application.Run();
        }
        [/highlight]

        Genau das funktioniert bei mir Der Clou hierbei ist, dass sich die Forms gegenseitig nicht kennen, aber trotzdem form1 die Funktion von form2 aufruft. Das ist die zentrale Zeile:

        Code:
        form1.SelectionChanged = form2.ChangeString;
        btw finde ich das Action<T> delegat wesentlich eleganter als normale delegate. Hab ich so auch noch nicht gesehen, werd ich ab jetzt aber bestimmt öfters mal benutzen, anstatt den teilweise doch recht müßigen Weg über Events zu gehen.

        Edit: Oh Sorry das ist jetzt Windows Forms... allerdings sollte das in WPF eigentlich analog funktionieren.

        Comment


        • #5
          Hmm,

          Funtkioniert bei mir irgendwie nicht habe jetzt folgendes versucht:

          im ersten Windows habe ich mir eine Methode geschrieben:

          [highlight=c#] public void NamenEingabe(string NeuerVorname, string NeuerNachname, string NeuerSBAutor)
          {
          VornameLbl.Content = NeuerVorname;
          NachnameLbl.Content = NeuerNachname;
          AutorLbl.Content = NeuerSBAutor;
          }[/highlight]
          und die rufe ich im Zweiten Fenster auf funktioniert aber nicht ...

          aufgerufen dann so:
          [highlight=c#] private void OKBtn_Click(object sender, RoutedEventArgs e)
          {
          Window1 MainFenster = new Window1();
          MainFenster.NamenEingabe(VornameEdt.Text, NachnameEdt.Text, SBAutorEdt.Text);
          this.Close();
          }[/highlight]

          was mir auch noch aufgefallen ist ist das man das Programm nachdem Klicken auf den Button nicht mehr so einfach geschlossen bekommt. Ich hoffe ihr wisst was falsch läuft.

          MfG
          Promos

          Comment


          • #6
            Hallo fanderlf,

            finde ich das Action<T> delegat wesentlich eleganter als normale delegate
            Ich finde Action<T> auch praktischer, da es schon vordefiniert ist


            Hallo Promos,

            schau dir das Beispiel von fanderlf noch mal an und v.a. wo Form1 und Form2 "verknüpft" werden (Lösung: In der Program-Klasse).


            mfG Gü
            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

            Comment


            • #7
              Ich hatte ja extra die zentrale Zeile noch herausgestellt^^

              Comment


              • #8
                Okay folgendes habe es so gemacht:

                Window 2:

                [highlight=c#]
                public Action<String> VornameChanged;
                public Action<String> NachnameChanged;
                public Action<String> AutorChanged;

                private void VornameSelection(string VornameString)
                {
                VornameChanged(VornameString);
                }

                private void NachnameSelection(string NachnameString)
                {
                NachnameChanged(NachnameString);
                }

                private void AutorSelection(string AutorString)
                {
                AutorChanged(AutorString);
                }

                private void OKBtn_Click(object sender, RoutedEventArgs e)
                {
                VornameSelection(VornameEdt.Text);
                NachnameSelection(NachnameEdt.Text);
                AutorSelection(SBAutorEdt.Text);
                this.Close();
                }
                [/highlight]

                Window1:

                [highlight=c#]
                public void VornameEingabe(string NeuerVorname)
                {
                VornameLbl.Content = NeuerVorname;
                }

                public void NachnameEingabe(string NeuerNachname)
                {
                NachnameLbl.Content = NeuerNachname;
                }

                public void AutorEingabe(string NeuerAutor)
                {
                AutorLbl.Content = NeuerAutor;
                }
                [/highlight]

                Verknüpfung:

                [highlight=c#]

                public static void Main() { SplashScreen splashScreen = new SplashScreen("resources/splashsreen.png");
                splashScreen.Show(true);
                Blubb.App app = new Blubb.App();
                app.InitializeComponent();

                Window1 MainFenster = new Window1();
                Window2 EinstellungsFenster = new Window2();


                EinstellungsFenster.NachnameChanged=MainFenster.Na chnameEingabe;
                EinstellungsFenster.VornameChanged = MainFenster.VornameEingabe;
                EinstellungsFenster.AutorChanged = MainFenster.AutorEingabe;

                EinstellungsFenster.Close();
                app.Run();
                }
                [/highlight]

                Nur kriege ich beim ausführen eine Fehler Meldung mit Objektinstanzblaa, dabei habe ich doch alles gemacht wie im Beispiel oder habe ich noch was übersehen

                MfG
                Promos

                Comment


                • #9
                  Das was Du machst ist ja keine direkte Kommunikation zwischen 2 Fenstern. Wenn ich das richtig verstanden habe, frägst Du in Window2 erstmal Daten ab und verwendest diese in Window1. Dies ist keine direkt Kommunikation zwischen den Fenster. Hier würde ich einen anderen Ansatz wählen.

                  Du erzeugst Dir eine Klasse die den Eingaben entspricht und reichst dieses weiter:

                  [highlight=c#]
                  public class Selection
                  {
                  public String Vorname { get; set; }
                  public String Nachname { get; set; }
                  public String Autor { get; set; }
                  }
                  [/highlight]

                  So, dann verpasst Du dem Window2 eine Property die Dir eine Instanz dieses Objekts zurück gibt, je nachdem was der Benutzer eingegeben hat:

                  [highlight=c#]
                  public Selection Selection
                  {
                  get
                  {
                  return new Selection
                  {
                  Vorname = VornameEdt.Text,
                  Nachname = NachnameEdt.Text,
                  Autor = SBAutor.Text
                  }
                  }
                  }
                  [/highlight]

                  So und letztendes noch irgendwas verarbeitendes für Window1:

                  [highlight=c#]
                  public void ChangeSelection(Selection selection)
                  {
                  //Mach was mit der Selection
                  }
                  [/highlight]

                  In der main dann so:

                  [highlight=c#]
                  public static void Main() {
                  SplashScreen splashScreen = new SplashScreen("resources/splashsreen.png");
                  splashScreen.Show(true);
                  Blubb.App app = new Blubb.App();
                  app.InitializeComponent();

                  Window1 MainFenster = new Window1();
                  Window2 EinstellungsFenster = new Window2();

                  EinstellungsFenster.ShowDialog();
                  MainFenster.ChangeSelection(EinstellungsFenster.Se lection));
                  MainFenster.Show();
                  app.Run();
                  }
                  [/highlight]

                  Comment


                  • #10
                    Hallo Promos,

                    Originally posted by fanderlf
                    Das was Du machst ist ja keine direkte Kommunikation zwischen 2 Fenstern.
                    Jetzt siehst du was passieren kann wenn die Frage nicht ganz korrekt gestellt werden. Besser wäre es gewesen du hättest eingangs deine Aufgabe kurz umrissen. Siehe hierzu auch Wie man Fragen richtig stellt.

                    Bitte berücksichtige dies das nächste mal

                    Aber das ist jetzt auch schon egal. Das soll aber nicht heißen dass du die Antworten von fanderlf (und zum Teil auch von mir) vergessen solltest. Das dort geschriebene sollte verwendet werden falls eine wirkliche Kommunikation von 2 Fenstern passieren soll.


                    mfG Gü
                    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                    Comment


                    • #11
                      Danke euch beiden Trotzdem für die Hilfe .

                      War schon irgendwie klar das es an mir gescheitert ist.

                      MfG
                      Promos

                      Comment


                      • #12
                        Naja... aber hat Dir denn meine Lösung jetzt geholfen oder ist das wieder nicht das was Du brauchst?

                        Comment


                        • #13
                          Hallo,

                          War schon irgendwie klar das es an mir gescheitert ist.
                          Das darfst du nicht so eng sehen, immerhin solltest du bei diesem Exkurs was gelernt haben.
                          Aber laut Kommunikationstheorie hast du recht: Der Sender ist verantwortlich dafür dass beim Empfänger die Botschaft so ankommt wie der Sender es beabsichtigt hat

                          Danke euch beiden Trotzdem für die Hilfe
                          Bitte gern geschehen.


                          mfG Gü
                          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                          Comment


                          • #14
                            An sich ist es das was ich brauche nur gibt es ein Problem mit der public Selection ... kann es sein das ich dafür noch eine using brauche ?

                            MfG
                            Promos

                            Comment


                            • #15
                              *lach* Das ist eine eigene Klasse die Du Dir anlegen musst. Die gibt es so natürlich nicht. Rechtsklick aufs Projekts -> Hinzufügen -> Klasse, dann benennst Du die Klasse Selection und schreibst den Code von mir hinein.
                              Wenn Du jetzt irgendwo einfach Selection hin schreibst und die Assembly als Verweis eingebunden ist in der Selection definiert ist, dann erscheint unter der Klassennamen so ein kleines rotes viereck. Da klickst Du drauf und dann wird das using automatisch hinzugefügt.

                              Wenn die Klasse im selben Projekt definiert ist, brauchst Du natürlich keine Assemlby als Verweis hinzufügen. So sollte es ja bei Dir der Fall sein

                              Comment

                              Working...
                              X