Laden...

Values vom UserControl an das MainWindow übergeben

Erstellt von xKushGene vor 7 Jahren Letzter Beitrag vor 7 Jahren 3.627 Views
X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 7 Jahren
Values vom UserControl an das MainWindow übergeben

Ich habe in einem Fenster 2 Tabitems, welche 2 UserControls beinhalten.
Im UserControl habe ich mehrere TextBoxes, welche ich über einen Klick auf einen Button, welcher in MainWindow ist über MessageBox ausgeben möchte.

Im UserControl habe ich dazu also folgende Properties:

public string Vorname
        {
            get { return vornameBox.Text; }
            set { vornameBox.Text = value; }
        }
        public string Nachname
        {
            get { return nachnameBox.Text; }
            set { nachnameBox.Text = value; }
        }

Wie komme ich nun von MainWindow aus an diese Properties heran um sie auszugeben? Wenn ich sie neu instanziere funktioniert es nicht.

5.658 Beiträge seit 2006
vor 7 Jahren

Hi xKushGene,

du mußt die Propertys als DependencyPropertys definieren, siehe dazu: How to: Implement a Dependency Property.

Dann kannst du im XAML darauf zugreifen und DataBinding verwenden, wie du es von anderen Controls gewohnt bist.

Weeks of programming can save you hours of planning

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 7 Jahren

Hmm Okay.
Kann damit leider nicht viel anfangen.
Habe noch ein Beispiel gefunden, womit ich leider auch nichts anfangen kann.

Mein Problem ist halt, dass ich nicht weiß, wie ich von MainWindow aus, auf eine Variable im UserControl zugreifen kann.

Folgenden Code habe ich jetzt:

public string Text
        {
            get
            {
                string s = (string)GetValue(TextProperty);
                return s;
            }
            set
            {
                if (Text != value)
                {
                    SetValue(TextProperty, value);
                }
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(addMitarbeiter_Control), new PropertyMetadata(null, Text_PropertyChanged));

        private static void Text_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            ((addMitarbeiter_Control)source).vornameBox.Text = (string)e.NewValue;
        }


        void vorname_TextChanged(object sender, TextChangedEventArgs e)
        {
            Text = vornameBox.Text;
        }

Ich denke, dass funktioniert auch soweit. Aber wie kann ich String Text in MainWindow ausgeben?

241 Beiträge seit 2010
vor 7 Jahren

Weise deinen UserControl mal einen Namen über "x:Name" zu. Anschließend kannst du im MainWindow sagen DEIN_NAME.Text <- falls deine Property wirklich "Text" heißt. Eine DependencyProperty brauchst du hier nicht. Die würdest du nur brauchen, wenn du darauf per Binding zugreifen möchtest.

WAGO Kontakttechnik GmbH & Co. KG / Software Notion
Softwareentwicklung

C# .NET with WPF, ASP, Xamarin and Unity
Personal Blog: Development Blog

3.170 Beiträge seit 2006
vor 7 Jahren

Hallo,

Eine DependencyProperty brauchst du hier nicht. Die würdest du nur brauchen, wenn du darauf per Binding zugreifen möchtest.

Das ist zwar richtig.
Die deutlich bessere Herangehensweise wäre aber in 99% der Fälle, die Werte in einem ViewModel zu speichern und dann an das UserControl zu binden.

[Artikel] MVVM und DataBinding

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

5.658 Beiträge seit 2006
vor 7 Jahren

Weise deinen UserControl mal einen Namen über "x:Name" zu. Anschließend kannst du im MainWindow sagen DEIN_NAME.Text

Genauso macht man es eben nicht!

Stattdessen würde man im UserControl die Steuerelemente (bzw. TextBoxen) an die DependencyPropertys binden, und dann im MainWindow die Propertys des UserControl an die entsprechenden Eigenschaften des ViewModels.

Weeks of programming can save you hours of planning

5.299 Beiträge seit 2008
vor 7 Jahren

komisch - bei mir haben die UserControls meist keinerlei DepProps - weil üflüssig und widerspräche MVVM.
Die werden einfach alle schön ans Viewmodel gebunden, und wenn im MainWindow was geklickst wird, dann ereignet sich nix inne UserControls, sondern im Viewmodel.
Und die Veränderung im Viewmodel spiegelt sich natürlich inne Ucls wieder - das ist ja das Prinzip Databinding.

Also genau genommen binde ich nicht die Ucls ans Viewmodel, sondern die einzelnen Controls, die auffm Ucl drauf sind.
Und - klar - Controls haben DepProps, aber die sind ja schon da, die brauch ich ja nicht dran-zu-coden.

Der frühe Apfel fängt den Wurm.

3.170 Beiträge seit 2006
vor 7 Jahren

Hallo ErfinderDesRades,

das ist eine Frage der Herangehensweise.

weil üflüssig und widerspräche MVVM.

Das jedenfalls ganz und gar nicht.
Wenn Du im UserControl einzelne Controls hast, die mit Werten aus einem VM gebunden werden sollen, dann gibt es 2 Möglichkeiten:

Entweder das UserControl trifft bereits Annahmen über das ViewModel (weiß also schon, wie dort die Properties benannt sind, damit man binden kann). Dann gibst Du dem UC einen DataContext, der die entsprechenden Properties enthält, und das Ganze funktioniert so wie Du es beschreibst. Dann bist Du aber auch gezwungen, ein solches ViewModel zu implementieren, dass zum UC passt.

Oder Du gehst noch einen Schritt weiter und entkoppelst das vollständig.
Dann halt auf die Art wie von MrSparkle beschrieben. Dann muss das UserControl überhaupt nix mehr über die Struktur des ViewModels wissen, aus dem die Daten kommen. Es können sogar die im UC angezeigten Werte aus unterschiedlichen ViewModels kommen. Dann kannst Du so ein UC wiederverwendbar machen, ohne bereits die ViewModel-Klasse dazu vorzugeben -> so ist es ja auch im Framework selbst, die ganzen Controls dort sind einfach nur Controls, aber ViewModels gibt es da noch nicht. Die schreibt der Benutzer des Controls eben selbst.

Edit: ich selbst benutze beide Varianten (bin da nicht puristisch), je nach Anwendungsfall des UC.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

5.299 Beiträge seit 2008
vor 7 Jahren

Dann bist Du aber auch gezwungen, ein solches ViewModel zu implementieren, dass zum UC passt. Ja, allerdings - bzw andersrum gedacht:
Ich implementiere Ucls, die zum Viewmodel passen 😁

Meine ucls kriegen über d: DataContext bereits im Designmode mitgeteilt, welches Viewmodel sie darstellen sollen.
Sie sind nicht als allgemein-verwendbar gedacht, wie etwa eine Textbox oder ein DatetimePicker.
Sondern wenn ich ein Viewmodel Person habe, mit Vor- und Nachname, und ich will Personen an mehreren Stellen im Programm anzeigen - oder auch nur allzu groß werdende Xaml-Dateien entzerren - dann bastel ich für Person ein ucl.

@TE: bei Interesse kannste auf Wpf-Sample son Sample downloaden - ich find die Vorgehensweise eiglich ziemlich überzeugend, weil man geniest beim proggen das Maximum an Wysiwyg und Intellisense-Hilfe.

Der frühe Apfel fängt den Wurm.

3.170 Beiträge seit 2006
vor 7 Jahren

Hallo,

Meine ucls kriegen über d:DataContext bereits im Designmode mitgeteilt, welches Viewmodel sie darstellen sollen. Sie sind nicht als allgemein-verwendbar gedacht, wie etwa eine Textbox oder ein DatetimePicker.

Völlig OK meiner Ansicht nach. Wie gesagt, ist das für mich eine Frage des Anwendungsfalls.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca