none
Argument Exception im Designer bei Zuweisung ViewModel im xaml RRS feed

  • Frage

  • Hallo Forum,

    ich erhalte im Designer eine ArgumentException, wenn ich ein ViewModel via...

    <Window.DataContext>
       <vm:MyViewModel />
    </Window.DataContext>

    zuweise. Es liegt wohl daran, dass ich im ViewModel eine Instanz von EF Entities erstelle und der Designer keinen Zugriff auf den ConnectionString hat.

    Gibt es hierfür eine saubere Lösung? Auf CodeBehind möchte ich verzichten.

    Verwende Visual Studio 2010 - wechsele aber gerne auf 2012/2013/2015, sofern dies den Einstieg in WPF MVVM erleichtert ;)

    Schöne Ostern,
    Jan

    Sonntag, 27. März 2016 21:05

Antworten

Alle Antworten

  • Hallo Jan,

    verwendest du irgend ein "behilfliches" Framework? Bei MVVM Light beispielsweise leitet man ViewModels von ViewModelBase ab das eine Eigenschaft IsInDesignMode unterstützt. Damit kannst du im VM entscheiden ob du die realen Daten oder nur Daten für den Designer lädst.

    Auf VS 2015 solltest du meiner Meinung nach umsteigen, sofern du nichts brauchst was explizit nur für 2010 existiert. Das 2015er arbeitet an einigen Stellen effizienter und der Arbeitsfluss ist besser. Auch Tools wie der Live Visual Tree können richtig hilfreich sein. Auch kannst du hier C# 6 verwenden.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Sonntag, 27. März 2016 21:45
    Moderator
  • Hi Tom,

    vielen Dank! Ich stehe noch am Anfang aber MVVM Light werde ich mir ansehen...

    Visual Studio 2015 installiert gerade ;)

    Etwas Verwirrung in Bezug auf das DataBinding verursachen noch die zwei unterschiedlichen Möglichkeiten, den Context zu erzeugen - "ObjectContext" und "DBContext":

    Beim ObjectContext sind die Entitiy-Collections vom Typ ObjectSet. -> Müssen diese in ObservableCollection umgewandelt werden damit das Binding richtig funktioniert?

    Beim DBContext ist scheinbar die Verwendung zusätzlicher Codegenerierungstemplates und eine Anpassung dieser erforderlich, damit die Entity-Collections vom Typ ObservableCollection sind. -> Ist das auch in VS2015 so? -> Warum ist das nicht "Default", da ObservableCollections im Zusammenspiel von EF + WPF (wenn ich richtig recherchiert habe) doch unabdingbar sind?

    Müssen Entity-Collections, die im ViewModel bereitgestellt werden, auch immer vom Typ ObservableCollection sein? Oder ist es ausreichend, wenn das ViewModel und die Properties INotifyPropertyChanged implementieren?

    Viele Grüße,
    Jan


    Sonntag, 27. März 2016 23:00
  • Hi Jan,
    so viele Fragen in einem Beitrag.

    Schau Dir mal an ObjectContext VS DBContext.

    Bei der Bindung mit dem ViewModel ist zu beachten, dass Eigenschaftswerte direkt angezeigt werden oder Eigenschaften Zeiger auf andere Objekte bereitstellen, wie das beispielsweise bei Listen ist. Änderungen anzuzeigender Werte werden mit NotifyPropertyChanged der Oberfläche mitgeteilt, damit sich diese die geänderten Werte für die Anzeige neu holt. Damit das auch durchgängig funktioniert, müssen sich die betreffenden Eigenschaften bei Änderungen melden. Die ObservableCollection gewährleistet das, weil sie INotifyCollectionChanged und INotifyPropertyChanged implementiert hat im Gegensatz zu z.B. zu der List(Of T)-Klasse, bei der diese Interfaces nicht implementiert sind.

    Wenn diese Benachrichtigungen von Änderungen der Liste nicht benötigt werden, kann auch eine List(Of T)-Klasse angewandt werden, die die Listenelemente einmalig z.B. bei der Bindung beim Anzeigen des Fensters bereitstellt.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Montag, 28. März 2016 05:26
  • Hallo Peter,

    sorry für die vielen Fragen auf einmal. Aber die Vielzahl an Ressourcen die sich z.T. auf unterschiedliche EF Versionen usw. beziehen verursachen teilweise Unklarheit. Dazu dann noch erforderliche "Hilfsmittel", damit z.B. der Designer bei "Standardtasks" keine Fehler auswirft (s.o.)... Etwas unschön. Aber gut, das Zusammenspiel WPF + MVVM ist vielversprechend und Einstiegshürden gibt es immer.

    Die Frage "ObservableCollection oder nicht" sowie "welcher Context" scheint für meine Zwecke (kleine Lernapplikation entwickeln) überhaupt nicht wesentlich: Beim ObjectContext werden die Properties der Entities sowieso mit "PropertyChanged" generiert. Verwende ich im ViewModel nun Collections dieser Entities, müssen die Setter der Collection-Properties eben auch "PropertyChanged" auslösen. Jedenfalls scheint das Binding so zu funktionieren...

    Auszug aus ViewModel:

    Private _Kunden As List(Of Kunden)
    Public Property Kunden As List(Of Kunden)
    	Get
    		' (From a In _ctx.Kunden).ToList()
    		Return _Kunden
    	End Get
    	Set(value As List(Of Kunden))
    		_Kunden = value
    		NotifyPropertyChanged("Kunden")
    	End Set
    End Property
    
    Private _SelectedKunde As Kunden
    Public Property SelectedKunde As Kunden
    	Get
    		Return _SelectedKunde
    	End Get
    	Set(value As Kunden)
    		_SelectedKunde = value
    		NotifyPropertyChanged("SelectedKunde")
    	End Set
    End Property


    "Kunden" ist in der View an ein ComboBox gebunden und die Properties von "SelectedKunde" jeweils an TextBoxes. Änderungen an Properties von "SelectedKunde" werden sofort in die Combobox reflektiert. Speicherung in Datenbank funktioniert auch.

    Oder ist dieser Ansatz schlecht?

    Viele Grüße
    Jan



    Montag, 28. März 2016 18:11
  • Hi Jan,
    das PropertyChanged bei "Kunden" und "SelectedKunde"  benötigst Du nur, wenn es im ViewModel Member gibt, die diese Eigenschaften verändern, z.B. ein Button-Klick oder auch eine anderes Navigationsereignis, und dann die Änderungen dazu führen sollen, dass die Oberfläche sich die anzuzeigenden Daten neu holen soll. Die Eigenschaft "Kunden" braucht sich nur dann zu melden, wenn eine neue Liste anzuzeigen ist, da sie nur den Verweis auf die Liste liefert. Wenn sich die Menge der Elemente in der Liste ändert, dann sollte die Eigenschaft natürlich auch PropertyChanged auslösen, damit die Anzeige aktualisiert wird.

    Um besser mit WPF und MVVM zurecht zu kommen, kannst Du auch erst einmal eine Datenzugriffsklasse erstellen, die nur Daten generiert (ohne Datenbank). Um dann auch das PropertyChanged zu ergründen, kannst Du in der Datenzugriffsklasse einen Zeitgeber einbauen, der die Inhalte der Datenobjekte ändert.

    Wenn das alles funktioniert, kannst Du den nächsten Schritt gehen und die Daten mit dem EF aus der Datenbank bereitstellen.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Montag, 28. März 2016 19:16
  • Hi Peter,

    prima, danke für den Tipp!

    Viele Grüße
    Jan

    Donnerstag, 31. März 2016 14:07