WPF: Variable vom aufrufenden Fenster holen
-
Sonntag, 17. März 2013 17:12
Hallo Forum,
Ich rufe aus einem Fenster ein anderes Fenster auf und möchte dort auf eine Variable des aufrufenden Fenster zugreifen. Im dortigen Behind-Code schaffe ich es nicht auf die Variable zuzugreifen,
lg heinz
'<Window x:Class="BilderPuzzleMain.MainWindow" Private Sub starteSpiel() Dim SpielWindow As New Window() SpielWindow.Owner = Me SpielWindow.Show() End Sub ' '<Window x:Class="BilderPuzzleSpiel.SpielWindow" Private Sub SpielLoaded(ByVal sender As Object, ByVal e As EventArgs) m_Bild = BilderPuzzleMain.MainWindow.m_BildAktuell 'HIER kennt er die Quelle nicht End Sub
Alle Antworten
-
Sonntag, 17. März 2013 18:15Moderator
Hallo,
ich würde an deiner Stelle im Konstruktor des 2. Fensters nach einer Instanz des 1. fensters oder der Variable verlangen. Ein Beipeil mit übergabe des Fensters:
Class Windows1 Inherits Windows Private Sub DoSome() Dim wnd As New Window2(Me) wnd.Owner = Me wnd.Show() End Sub Public ABC As String = "" End Class Class Windows2 Inherits Windows Private wnd As Window1 = Nothing Private Sub New(wnd As Window1) Me.wnd = wnd End Sub Private Sub DoSome() MessageBox.Show(wnd.ABC) End Sub End Class
Wenn du nur die Variable übergibst, dann brauchst du Sie nicht public machen.
<Code:13/> - Koopakiller [kuːpakɪllɐ]
Webseite | Code Beispiele | Facebook | Snippets- Bearbeitet KoopakillerMicrosoft Community Contributor, Moderator Sonntag, 17. März 2013 18:16 Codekorrektur
- Als Antwort markiert Heinz9 Sonntag, 17. März 2013 22:26
-
Sonntag, 17. März 2013 18:20Hi,ich würde die zu übergebenden Variableninhalte in Objekte auslagern, auf die über statische Variablen oder Eigenschaften zugegriffen werden kann. Damit entfällt die Notwendigkeit der gegenseitigen Kenntnis der Window-Klassen.--
Peter Fleischer -
Sonntag, 17. März 2013 19:29
Hallo, Peter,
hört sich gut an, aber wie mache ich das? Bzw. wo kann ich das nachlesen?,
lg heinz
-
Sonntag, 17. März 2013 19:31
Hallo Koopakiller,
danke, das funktioniert, obwohl mir nicht ganz klar warum,
lg heinz
-
Sonntag, 17. März 2013 20:29Moderator
Das funktioniert weil die Instanz der Form nur ein Verweis auf einen bereich im Arbeitsspeicher ist. Wenn du nun die Instanz übergibst, dann übergibst du nur den Verweis auf den Arbeitsspeicher. Das heißt, das Window2 direkt auf Window1 zugreifen kann.
Zu den Statischen Eigenschaften: http://openbook.galileocomputing.de/einstieg_vb_2008/visual_basic_kap_05_006.htm
Wichtig ist, das der Wert Anwendungsweit gleich ist udn man somit Daten austausche kann.
<Code:13/> - Koopakiller [kuːpakɪllɐ]
Webseite | Code Beispiele | Facebook | Snippets
- Bearbeitet KoopakillerMicrosoft Community Contributor, Moderator Sonntag, 17. März 2013 20:33
-
Montag, 18. März 2013 08:02
Hi,
um Daten in einem Programm zwischen verschiedenen Objekten auszutauschen, kann man den Verweis auf den Container mit den Variablen übergeben. So kann man beispielsweise eine Variable in einer Form einer andern Form im Konstruktor übergeben, indem man den Verweis auf sich selbst, d.h. auf die aktuelle Form, mitreicht. Diese Arbeitsweise hat jedoch den Nachteil, dass sich alle Klassen kennen müssen und bei komplexeren Projekten der Überblick verloren gehen kann, insbesondere bei Tests.Eine alternative Lösung ist die Ablage der Variablenwerte in einem separaten Datenobjekt, welches alle anderen Objekte (Klassen) kennen. Da erübrigt sich die Notwendigkeit, dass unterschiedliche Klassen sich gegenseitig kennen müssen. Für die Ablage der Variablenwerte ist eine Klasse zu nutzen, die nur einmalig instanziiert wird, d.h. es gibt im Projekt nur ein Objekt vom Typ dieser Klasse. Das kann man erreichen, indem man einen statischen Verweis auf dieses Datenobjekt hat. Statische Zugriffe lassen sich in VB am einfachsten in Moduln verwaltet.
Nachfolgend ist ein Beispiel zur Demonstration dargestellt:
Class1 - Klasse für das Datenobjekt:
Imports System.ComponentModel
''' <summary> ''' Klasse zur Erzeugung von Datenobjekten, ''' in denen Werte gespeichert und wieder bereitgestellt werden können ''' </summary> ''' <remarks></remarks> Public Class Class1 Implements INotifyPropertyChanged ' Interface für das Melden von Änderungen ''' <summary> ''' interne Variable zum Puffern eines Wertes ''' </summary> ''' <remarks></remarks> Private _daten As String ''' <summary> ''' In der Assembly sichtbare Eigenschaft für das Puffern eines Wertes ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Friend Property Daten As String Get Return Me._daten ' gepufferten Wert bereitstellen End Get Set(value As String) ' Abfrage, ob veränderter Wert zu puffern ist If Me._daten <> value Then Me._daten = value ' Melden, dass in der Eigenschaft gepufferter Wert verändert wurde OnPropertyChanged("Daten") End If End Set End Property ''' <summary> ''' Ereignis für das Melden von Veränderungen des gepufferten Wertes ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged ''' <summary> ''' interne Methode zum Auslösen des Meldevorganges ''' </summary> ''' <param name="propName"></param> ''' <remarks></remarks> Private Sub OnPropertyChanged(propName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End ClassModul1 - statische Klasse
''' <summary> ''' statische Klasse, auf deren Innereien ohne Objektinstanziierung zugegriffen werden kann ''' </summary> ''' <remarks></remarks> Module Module1 ''' <summary> ''' interner Puffer für die Ablage des Verweises auf eine Instanz des Datenobjektes ''' </summary> ''' <remarks></remarks> Private _datenobjekt As Class1 = Nothing ''' <summary> ''' statische Eigenschaft, die den Verweis auf das Datenobjekt bereitstellt ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Friend ReadOnly Property Datenobjekt As Class1 Get ' Prüfen, obe es bereits ein Datenobjekt gibt If _datenobjekt Is Nothing Then _datenobjekt = New Class1 ' Bereitstellung des Verweises auf das Datenobjekt Return _datenobjekt End Get End Property End Module
Form1:
''' <summary>
''' 1. Form ''' </summary> ''' <remarks></remarks> Public Class Form1 ''' <summary> ''' TextBox in der Form ''' </summary> ''' <remarks></remarks> Private tb As New TextBox With {.Dock = DockStyle.Top} ''' <summary> ''' Befehlsschaltfläche in der Form ''' </summary> ''' <remarks></remarks> Private WithEvents btn As New Button With {.Dock = DockStyle.Top, .Text = "Speichern"} ''' <summary> ''' Beim Laden der Form-Instanz Anfangszustände setzen ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Alle Steuerelemente platzieren (anstelle der Arbeit mit dem Designer) Me.Controls.AddRange(New Control() {btn, tb}) ' weitere Form zur Anzeige bringen Call (New Form2).Show() End Sub ''' <summary> ''' Klick-Ereignis der Befehlsschaltfläche behandeln ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click ' Inhalt der text-Eigenschaft der TextBox im Datenobjekt ablegen Module1.Datenobjekt.Daten = tb.Text End Sub End Class
Form 2:
Imports System.ComponentModel ''' <summary> ''' Weitere Form, die Daten von "außen" anzeigt ''' </summary> ''' <remarks></remarks> Public Class Form2 ''' <summary> ''' TextBox in der Form ''' </summary> ''' <remarks></remarks> Private tb As New TextBox With {.Dock = DockStyle.Top} ''' <summary> ''' Beim Laden der Form-Instanz Anfangszustände setzen ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Alle Steuerelemente platzieren (anstelle der Arbeit mit dem Designer) Me.Controls.AddRange(New Control() {tb}) ' Ereignis der Datenänderungen im Datenobjekt fangen und verarbeiten AddHandler Module1.Datenobjekt.PropertyChanged, Sub(da As Object, pc As PropertyChangedEventArgs) ' Methode, die beim Eintreten des Ereignisses abgearbeitet wird ' Abfrage, ob sich der Inhalt der Eigenschaft "Daten" geändert hat If pc.PropertyName = "Daten" Then ' geänderten Wert in die TextBox schreiben tb.Text = Module1.Datenobjekt.Daten End If End Sub End Sub End Class
--
Viele Gruesse
Peter
- Als Antwort vorgeschlagen Peter FleischerMVP Montag, 18. März 2013 08:09
- Bearbeitet Peter FleischerMVP Montag, 18. März 2013 08:11
- Bearbeitet Peter FleischerMVP Montag, 18. März 2013 08:13
- Bearbeitet Peter FleischerMVP Montag, 18. März 2013 08:16
- Als Antwort markiert Heinz9 Montag, 18. März 2013 11:34
-
Montag, 18. März 2013 11:33
Hallo Peter,
das Beispiel ist sehr gut,
lg heinz
-
Montag, 18. März 2013 13:22Hi,ich hatte da gleich noch NotifyPropertyChanged eingebaut, da diese Frage bestimmt als nächste Frage gekommen wäre.--
Peter Fleischer -
Mittwoch, 20. März 2013 09:50
Hallo Peter,
ja die Methode ist ausgesprochen hilfreich,
lg heinz

