Windows Phone 8: Zentrale Datenhaltung mittels einfachem ViewModel

Wo halte ich meine Daten? Wo ist meine Logik? Wer steuert eigentlich die App intern?

Immer wieder stoße ich auf sehr wilde Apps, die sich mit wildestem Spaghetti-Code hinter jedem Button-Click-Ereignis ihre Daten von diversen Quellen zusammen suchen, und dabei ein und den selben Code 4x schreiben.

Dabei geht es doch auch viel einfacher. Man steuert alles über eine zentrale Klasse und tut nur noch das Nötigste in der eigentlichen Phone-Page. Nämlich mit einer zentralem ViewModel. Entwicklungsesotheriker und CleanCode-Fanatiker werden bestimmt meckern, das sei ja “schmutzig”, denen Antworte ich aber, “Es ist pragmatisch, einfach und ich werde sogar fertig mit meiner App und sterbe nicht in Schönheit”.

Was benötigt man? Eine zentrale Klasse (das ViewModel), das alles andere steuert, je nach Komplexitität auch Unter-ViewModels. Diese Klasse wird einmal statisch bei Anwendungsstart erzeugt und steht von da an, von überall zur Verfügung.

Hier meine einfachste Version eines ViewModels:

using System.Collections.ObjectModel;
using System.ComponentModel;

namespace PhoneViewModelSample
{
    public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Customer> _customerList;

        public ObservableCollection<Customer> CustomerList
        {
            get 
            {
                if (_customerList == null)
                {
                    _customerList = new ObservableCollection<Customer>();
                    for (int i = 0; i < 100; i++)
                    {
                        var newCustomer = new Customer();
                        newCustomer.Name = "Kunde " + i;
                        newCustomer.Id = i;
                        _customerList.Add(newCustomer);
                    }
                }
                return _customerList; 
            }
            set { _customerList = value; OnPropertyChanged("CustomerList"); }
        }

        #region INotifyProperty - Stuff

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        private Customer _selectedCustomer;
        public Customer SelectedCustomer
        {
            get 
            {
#if DEBUG
                if (DesignerProperties.IsInDesignTool)
                {
                    _selectedCustomer = new Customer();
                    _selectedCustomer.Id = 11;
                    _selectedCustomer.Name = "Oliver Scheer Inc.";
                }
#endif
                return _selectedCustomer; 
            }
            set { _selectedCustomer = value; }
        }
    }
}

Die dazugehörige Customer-Klasse:

namespace PhoneViewModelSample
{
    public class Customer
    {
        public string Name { get; set; }

        public int Id { get; set; }
    }
}

Die Klasse MyViewModel wird zentral in der App.xaml instanziert und steht dann allen UI-Elementen in der App sofort zur Verfügung. D.h. ich kann sofort gegen Elemente aus dem ViewModel binden.

image

Damit man auch aus dem Code drauf zugreifen kann, habe ich eine Statische Variable in der App-Klasse erzeugt, die dieses Resources “TheViewModel” auch im Code anbietet.

 

 

public static MyViewModel TheViewModel { get; set; }

private void InitializePhoneApplication() { if (phoneApplicationInitialized) return; // Create the frame but don’t set it as RootVisual yet; this allows the splash // screen to remain active until the application is ready to render. RootFrame = new PhoneApplicationFrame(); RootFrame.Navigated += CompleteInitializePhoneApplication; TheViewModel = (MyViewModel)Resources["TheViewModel"]; // Handle navigation failures RootFrame.NavigationFailed += RootFrame_NavigationFailed; // Handle reset requests for clearing the backstack RootFrame.Navigated += CheckForResetNavigation; // Ensure we don’t initialize again phoneApplicationInitialized = true; }

 

Das Video, das das ganze noch mal langsam erklärt befindet sich hier.

Der Sourcecode zur App kann hier heruntergeladen werden.

One thought on “Windows Phone 8: Zentrale Datenhaltung mittels einfachem ViewModel”

  1. Hallo Oliver,

    Selbst als “Entwicklungsesotheriker und CleanCode-Fanatiker” stellt Dich dafür niemand an den Pranger :D. Jedoch muss man bei dieser Lösung darauf achten, dass die gehaltenen Daten möglichst Stateless sind, um bei komplexeren Lösungen nicht gleich in einer Backstack Hell zu landen. Wer einmal schnell einen verschachtelten Wizard (z.B. zur Konfiguration) bauen wollte, weiß was Ich meine :-).

    Viele Grüße,
    Chris

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>