Donnerstag, 24. Mai 2012


Artikel

September 2010 | Artikel

Tipps und Tricks zum MVVM-Pattern Fortsetzung, Teil 4

Teil 1   Teil 2   Teil 3   Teil 4   

Auch die in diesem Artikel verwendete Beispielanwendung benutzt zum Laden von Personen Data-Provider. Dazu ist das Interface IPersonDataProvider definiert, das die entsprechenden Load-Methoden enthält:

  1. public interface IPersonDataProvider
  2. {
  3. List<PersonList> LoadPersonLists();
  4. List<Person> LoadPersons(int personListID);
  5. }

Das Interface wird von der Klasse PersonDataProvider implementiert, die die Personendaten via Entity Framework aus der Datenbank lädt (Listing 7).

  1. public class PersonDataProvider : IPersonDataProvider
  2. {
  3. ...
  4. public List<Person> LoadPersons(int personListID)
  5. {
  6. var ctx = new PersonenDBEntities();
  7. var query = from person in ctx.Person
  8. where person.PersonListID == personListID
  9. select person;
  10. return query.ToList();
  11. }
  12. }

Ebenfalls wird das Interface von der Klasse PersonDesignDataProvider implementiert. Diese Klasse erstellt in der Methode LoadPersons einfach eine Liste mit vier Person-Objekten (Listing 8).

  1. public class PersonDesignDataProvider : IPersonDataProvider
  2. {
  3. ...
  4. public List<Person> LoadPersons(int personListID)
  5. {
  6. var list = new List<Person>();
  7. list.Add(new Person { FirstName = "Silvester", LastName = "Stallone");
  8. list.Add(new Person { FirstName = "Cameron", LastName = "Diaz" });
  9. list.Add(new Person { FirstName = "Sean", LastName = "Penn" });
  10. list.Add(new Person { FirstName = "Sharon", LastName = "Stone" });
  11. AddImages(list);
  12. return list;
  13. }
  14. ...
  15. }

Das ViewModel nutzt zum Erstellen eines DataProviders die PersonDataProviderFactory-Klasse bzw. deren statische Methode GetPersonDataProvider (Listing 9). Darin wird geprüft, ob die Anwendung sich im Designmodus befindet. Falls ja, wird eine PersonDesignDataProvider-Instanz zurückgegeben, ansonsten eine PersonDataProvider-Instanz.

  1. public class PersonDataProviderFactory
  2. {
  3. public static IPersonDataProvider GetPersonDataProvider()
  4. {
  5. if (DesignerProperties.GetIsInDesignMode(new FrameworkElement()))
  6. return new PersonDesignDataProvider();
  7. return new PersonDataProvider();
  8. }
  9. }

Im MainViewModel wird direkt im Konstruktor die LoadPersons-Methode aufgerufen, falls sich das MainViewModel im Designmodus befindet. In der LoadPersons-Methode wird der Design-Data-Provider erstellt und die entsprechenden Personen in einem PersonViewModel gekapselt sowie zur _persons Collection hinzugefügt (Listing 10).

  1. public class MainViewModel : ViewModelBase
  2. {
  3. ...
  4. public MainViewModel()
  5. {
  6. ...
  7. if (DesignerProperties.GetIsInDesignMode(new FrameworkElement()))
  8. {
  9. LoadPersons(1);
  10. _personsDefaultView.MoveCurrentToFirst();
  11. }
  12. }
  13. ...
  14. private void LoadPersons(int personListID)
  15. {
  16. _persons.Clear();
  17. IPersonDataProvider dataProvider = PersonDataProviderFactory.GetPersonDataProvider();
  18. foreach (Person p in dataProvider.LoadPersons(personListID))
  19. {
  20. _persons.Add(new PersonViewModel(p));
  21. }
  22. }
  23. ...
  24. }

Wird das Window, das dieses MainViewModel verwendet, nun in einem Werkzeug wie Expression Blend geöffnet, werden die im PersonDesignDataProvider definierten Personen angezeigt (Abb. 6). Ein DataTemplate lässt sich aufgrund dieser Designdaten sehr leicht in Expression Blend erstellen.

Wie geht’s weiter?

Das MVVM-Pattern bietet einige Stellen, an denen die Umsetzung nicht auf den ersten Blick klar ist. Dieser Artikel hat versucht, einige dieser Stellen klarzustellen. Im Endeffekt macht ein Entwickler alles richtig, wenn seine ViewModels „unit-testbar“ sind, der Designer das UI hervorragend in Expression Blend bearbeiten kann und die Codebehind-Dateien der Fenster außer Event Handlern zum Anzeigen von Dialogen keine Logik enthalten.

Thomas Claudius Huber arbeitet als Senior Consultant und Trainer bei der Trivadis AG. Nach seinem umfassenden Handbuch zur WPF hat er kürzlich auch sein umfassendes Handbuch zu Silverlight fertiggestellt. Nähere Informationen dazu unter www.thomasclaudiushuber.com/silverlight.

Teil 1   Teil 2   Teil 3   Teil 4   

Kommentare

Gravatar Anonym 06.10.2010
um 12:15 Uhr
Wie siehts mit dem SourceCode aus? #zitieren
Gravatar Mike 05.11.2010
um 10:08 Uhr
Hallo Thomas,
super Tutorial !
allerdings wäre für mich, um noch ein wenig tiefergehen zu können, die Solution sehr hilfreich.
Ich habe u.a. Probleme mit dem CommandManager (keine Resource gefunden).
Gruss
Mike
#zitieren
Gravatar Katharina Friedrich 05.11.2010
um 10:48 Uhr
Hallo Mike & Co.,

der Quellcode zu dem Artikel ist unter folgendem Link zu finden:
http://it-republik.de/dotnet/dotnet-magazin-ausgaben/Office-2010-000410.html

Ich hoffe, dass ich weiterhelfen konnte.
Viele Grüße aus der .NET-Magazin-Redaktion,
Katharina
#zitieren
Gravatar Mike 05.11.2010
um 13:39 Uhr
Hallo Katharina,

vielen Dank für den Link zum Download.
Leider ist die Solution nicht lauffähig und stürzt bei zeile 35 im MainWindow.xaml.cs ab.
(var dlg = new OpenListDialog { Owner = this, WindowStartupLocation = WindowStartupLocation.CenterOwner };)
Man kann also keine Liste laden und somit hat man auch keine MVVM Demo von dieser schönen Anleitung.

Gruss
Mike
#zitieren
Gravatar Thomas Claudius Huber 05.11.2010
um 17:05 Uhr
Hallo Mike,

freut mich, wenn Dir das Tutorial gefällt. Damit die Demo-Anwendung läuft, musst Du die Datenbank, die ebenfalls mit im Quellcode enthalten ist, auf Deinen SQL-Server installieren und in der App.Config im Projekt MVVM.Client den ConnectionString entsprechend anpassen.

Falls es nicht klappt, schreib mir einfach eine Mail (Adresse steht am Ende des Artikels oder einfach über www.thomasclaudiushuber.com/contact.php)

Viele Grüsse,
Thomas
#zitieren
Gravatar Thomas Claudius Huber 05.11.2010
um 17:07 Uhr
... Adresse steht nicht am Ende des Online-Artikels. Somit Kontakt einfach über www.thomasclaudiushuber.com/contact.php. 8-)

Beste Grüsse,
Thomas
#zitieren