PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : WPF Databind: Graue Haare.


Yavion
2011-12-14, 17:38:47
Hat sich erledigt. Kann gelöscht werden.
Meine Frage wurde hier gestellt und beantwortet:
http://social.msdn.microsoft.com/Forums/de-CH/wpfde/thread/4d5be7f6-5101-47d6-b696-529bf4a89ab9

PatkIllA
2011-12-14, 22:45:42
Datenbindung ist vor allem dafür da, die ganzen Properties nicht auf den Gui Klassen zu haben.
Bei einfachen Fällen kannst du das Datencontext Objekt auch direkt im XAML erstellen.

Statische Properties solltest du besser gleich verdrängen (unabhängig von WPF)

Monger
2011-12-14, 23:28:24
Wenn ich das richtig noch im Kopf habe, kannst du ein Property explizit über einen Namen registrieren, und damit kann es dann auch von anderen Controls für Databinding über den Namen gefunden werden. Alle Controls die x:Name in XAML deklarieren, machen das halt bereits implizit.

Die Grundidee von XAML ist ja, dass logische Zusammenhänge auf der Oberfläche bereits ohne Code-Behind modelliert werden können. Ein XAML Dokument sollte deshalb bereits ohne jeden Code grundsätzlich schonmal ausführbar sein.

Deshalb: geschickter ist es in aller Regel, alle abhängigen Daten (wie in deinem Fall irgendein Property) als Resource in WPF zur Verfügung zu stellen, und dagegen zu binden.

Yavion
2011-12-15, 10:18:15
Genau das war der Plan. Es quasi nicht Windows.Forms Style zu machen sondern wirklich die Bindings nach Möglichkeit in XAML zu basteln.
Irgendwie hatte ich aber Schwierigkeiten, auf Daten zuzugreifen, die ich eben nicht in XAML initialisiere sondern durch den CodeBehind erzeuge (z.B. durch einen Konstruktoraufruf a la :
This.w2= new Window2(meineDaten);
Abhilfe schaffte dann diese Zeile im Code Behind (hier von Window2):

this.DataContext=this;

(Ich frage mich ehrlich gesagt, warum das nicht Default-Einstellung ist. I.D.R. erhält ja eine Form seine Daten von einer Quelle (meinetwegen ein ViewModel) die in der Form referenziert ist, oder nicht?)

PatkIllA
2011-12-15, 10:51:37
this.DataContext=this;

(Ich frage mich ehrlich gesagt, warum das nicht Default-Einstellung ist. I.D.R. erhält ja eine Form seine Daten von einer Quelle (meinetwegen ein ViewModel) die in der Form referenziert ist, oder nicht?)
Die Quelle sollte aber nicht die Gui sein, sondern extra Klassen. Man will ja Gui und Model trennen.

<Window x:Class="Lovion.MarkerMigration.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LocalNamespace"
Title="MainWindow">
<Window.DataContext>
<local:MigrationPresenter />
</Window.DataContext>
<Grid>
....
</Grid>
</Window>

Außerdem vererbt sich der DataContext durch den VisualTree.

Die Datenbinding in Kombination mit INotifyPropertChanged, ValueConverter, DataTemplate erlauben unglaublich mächtige Guis, die sich den Model anpassen. Da braucht man aber mindestens einige Wochen oder Monate bis man das mit allen Möglichkeiten versteht und einsetzen kann.

Monger
2011-12-15, 12:57:32
Irgendwie hatte ich aber Schwierigkeiten, auf Daten zuzugreifen, die ich eben nicht in XAML initialisiere sondern durch den CodeBehind erzeuge (z.B. durch einen Konstruktoraufruf a la :
This.w2= new Window2(meineDaten);


Die gesamten WPF Controls werden nicht bei der Instanziierung des Windows initialisiert, sondern erst mit Ende des Loaded Events. Deshalb: wenn du z.B. Resourcen initialisieren willst, mach das im Loaded Event Handler.

Yavion
2011-12-15, 13:50:01
Danke für die Anregungen!

robobimbo
2011-12-15, 18:35:05
Vor allem im Silverlight Bereich gibts da echt gute Tutorials mit ViewModel - vor allem das MVVMLight Framework kann ich dir da ans Herz legen. Vom dem Autor der Bibliothek gibts auch gute Talks darüber.

Erhöht die Testbarkeit, und es lässt sich damit auch leichter im Editor (Blend) arbeiten.

Yavion
2011-12-17, 11:58:32
So langsam fängt es an Spaß zu machen.
@PatkIllA: Ich habe es jetzt auch genau so gemacht, also den DataContext des Windows direkt auf die View setzen.

Ich hatte da nur den Effekt, dass VS2010 die Properties, die ich im Code definiert habe und an die ich binden wollte, im Properties-Fenster nicht angezeigt hat. Das scheint aber ein VS-Effekt zu sein und tritt regelmäßig dann auf, wenn ich neue Properties einfüge. Nach dem Neu-Kompilieren geht es dann.

PatkIllA
2011-12-17, 12:00:07
Ich hatte da nur den Effekt, dass VS2010 die Properties, die ich im Code definiert habe und an die ich binden wollte, im Properties-Fenster nicht angezeigt hat. Das scheint aber ein VS-Effekt zu sein und tritt regelmäßig dann auf, wenn ich neue Properties einfüge. Nach dem Neu-Kompilieren geht es dann.Dass man dauernd neu kompilieren muss ist leider so. Neue Klassen oder Controls kennt der Editor auch erstmal nicht.
Ich schreib die Bindings normalerweise direkt im XAML hin. Den Editor benutze ich mehr als Preview.

Yavion
2012-03-15, 10:06:19
Nachtrag:

Nachdem ich jetzt wieder mal darauf gestoßen bin, dass VS (manchmal?) einfach nicht in der Lage zu sein scheint, einen DataContext zu erkennen, den ich nicht im XAML erschaffe, schildere ich nochmal meine Erfahrung,in der Hoffnung jemand kann mir sagen, was ich falsch mache oder dass MS hier Mist gebaut hat.





Situation: Ich habe ein "MainWindow" und ein "HelperWindow".
HelperWindow soll den selben DataContext haben (das selbe ViewModel) wie MainWindow.

ich habe das so gelöst dass ich eine Referenz auf MainWindow dem Konstruktor von HelperWindow übergebe, so dass ich im HelperWindow etwas tun kann wie:
this.DataContext=MainWindow.DataContext;
oder this.Model = MainWindowModel;

In dieser Hinsicht habe ich alle Versuche durch: Egal ob im Konstruktor oder durch benutzung des Loaded-Events. Der effekt ist stehts der, dass VS den DataContext nicht erkennt und tut als gäbe es gar keinen DataContext.


Was geht ist eine neue Instanz von Model im XAML anzulegen (siehe Code PatKI||A.
Dann kann man alles bequem per Property-Editor binden, hat aber 2 Instanzen von View-Model (=Mist).
Weil man ja den DataContext im Code schon gesetzt hat s.o., kann man diesen Teil hier danach wieder löschen:

<Window.DataContext>
<local:MigrationPresenter />
</Window.DataContext>


Und: Das Programm kompiliert und bleibt lauffähig.

Trotzdem. Ich kann dieses Verhalten nicht nachvollziehen. :confused:

PatkIllA
2012-03-15, 11:10:16
Wir schreiben das einfach alles direkt hin und der Editor ist nur eine Vorschau für die Struktur der Elemente.

Monger
2012-03-15, 11:41:01
Eine echte Antwort habe ich nicht, aber ich hab auch festgestellt, dass der Austausch von Resourcen zwischen verschiedenen Fenstern mitunter hässlich ist.

Resourcen werden ja von unten nach oben aufgelöst, d.h. wenn ein Control einen DataContext sucht, sucht es im Baum nach oben bis es einen findet. Das Fenster ist übrigens NICHT die Wurzel, sondern App.xaml.

Ich hab z.B. globale Ressourcen die für beide Fenster gelten dann gerne in der App.xaml deklariert, dann können unten drunter beliebig Fenster geöffnet und geschlossen werden, ohne dass die Datenhaltung des eigentlichen Programms bedroht wird.