• Blog
  • Info Support
  • Career
  • Training
  • International Group
  • Info Support
  • Blog
  • Career
  • Training
  • International Group
  • Search
logo InfoSupport
  • Latest blogs
  • Popular blogs
  • Experts
      • Alles
      • Bloggers
      • Speakers
  • Meet us
  • About us
    • nl
    • en
    • .NET
    • Advanced Analytics
    • Agile
    • Akka
    • Alexa
    • Algorithms
    • Api's
    • Architectuur
    • Artificial Intelligence
    • ATDD
    • Augmented Reality
    • AWS
    • Azure
    • Big Data
    • Blockchain
    • Business Intelligence
    • Cloud
    • Code Combat
    • Cognitive Services
    • Communicatie
    • Containers
    • Continuous Delivery
    • CQRS
    • Cyber Security
    • Dapr
    • Data
    • Data & Analystics
    • Data Science
    • Data Warehousing
    • Databricks
    • DataOps
    • DevOps
    • Digital Days
    • Docker
    • eHealth
    • Enterprise Architecture
    • Hacking
    • Infrastructure & Hosting
    • Innovatie
    • Integration
    • Internet of Things
    • Java
    • Machine Learning
    • Microservices
    • Microsoft
    • Microsoft Bot Framework
    • Microsoft Data Platform
    • Mobile Development
    • Mutation Testing
    • Open source
    • Pepper
    • Power BI
    • Privacy & Ethiek
    • Python
    • Quality Assistance & Test
    • Quality Assurance & Test
    • Requirements Management
    • Scala
    • Scratch
    • Security
    • SharePoint
    • Software Architecture
    • Software development
    • Software Factory
    • SQL Server
    • SSL
    • Start-up
    • Startup thinking
    • Stryker
    • Test Quality
    • Testing
    • TLS
    • TypeScript
    • Various
    • Web Development
    • Web-scale IT
    • Xamarin
    • Alles
    • Bloggers
    • Speakers
Home » Windows Phone 7 MVVM ViewModel ideas
  • Windows Phone 7 MVVM ViewModel ideas

    • By Erno de Weerd
    • .NET 10 years ago
    • .NET 0 comments
    • .NET .NET
    Windows Phone 7 MVVM ViewModel ideas

    While writing a Windows Phone 7 application I started out NOT using MVVM. The prototype I started out with to get a feel for the required screens and navigation did not contain much logic and relied on data from a web service. At the time it felt like overkill to use MVVM. After trying to add more functionality and implementing the Marketplace requirements MVVM made a lot more sense.

    Here is the first implementation I made of a ViewModel base class:

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Windows;
    
    namespace MVVM
    {
        public class ViewModelBase<T> : INotifyPropertyChanged
        {
            public App Application
            {
                get
                {
                    return App.Current as App;
                }
            }
    
            #region INotifyPropertyChanged Implementation
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void NotifyPropertyChanged<TProperty>(
                Expression<Func<T, TProperty>> propertyExpression)
            {
                MemberExpression memberExpression = propertyExpression.Body
                    as System.Linq.Expressions.MemberExpression;
                if (memberExpression == null || (memberExpression != null &&
                    memberExpression.Member.MemberType != MemberTypes.Property))
                {
                    throw new ArgumentException(
                        &quot;The specified expression does not represent a valid property&quot;);
                }
                OnPropertyChanged(memberExpression.Member.Name);
            }
    
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler p = PropertyChanged;
                if (p != null)
                {
                    p(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }
    }
    

    A very basic implementation and using reflection to have a rename-safe implementation of INotifyPropertyChanged.

    I also added a property named Application that allows fast access to the App object because the App object contains cache web service data and nearly all ViewModels use it.

    When I was looking for a developer friendly way of implementing globalization and localization because I didn’t like the too complex bindings in the MSDN. I stumbled on this post and adapted it a bit for the next version of my ViewModel base class:

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Windows;
    
    namespace MVVM
    {
        public class ViewModelBase<T> : INotifyPropertyChanged
        {
            private static Example.Resources.Cultures.AppResources _uiTexts = new Resources.Cultures.AppResources();
    
            public Example.Resources.Cultures.AppResources UITexts
            {
                get
                {
                    return _uiTexts;
                }
            }
    
            public void ChangeLanguage(string language)
            {
                Example.Resources.Cultures.AppResources.Culture = new System.Globalization.CultureInfo(language);
                OnPropertyChanged(&quot;UITexts&quot;);
            }
    
            public App Application
            {
                get
                {
                    return App.Current as App;
                }
            }
    
            #region INotifyPropertyChanged Implementation
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void NotifyPropertyChanged<TProperty>(
                Expression<Func<T, TProperty>> propertyExpression)
            {
                MemberExpression memberExpression = propertyExpression.Body
                    as System.Linq.Expressions.MemberExpression;
                if (memberExpression == null || (memberExpression != null &&
                    memberExpression.Member.MemberType != MemberTypes.Property))
                {
                    throw new ArgumentException(
                        &quot;The specified expression does not represent a valid property&quot;);
                }
                OnPropertyChanged(memberExpression.Member.Name);
            }
    
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler p = PropertyChanged;
                if (p != null)
                {
                    p(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }
    }
    

    (I am not too happy about the name of the property UITexts, but I dislike the Resources from the original web site as I find it is too generic)

    This structure allows two important things opposed to the MSDN solution:

    1. Easy use of localized texts in my Views like this:
    2. <TextBlock x_Name=&quot;PageTitle&quot;
      
                           Text=&quot;{Binding UITexts.LocationsHeader}&quot; />
      
    3. Easy testing of the localized texts by calling the ChangeLanguage method. By default the resources follow the Phone’s UI language.

    On the other hand it has drawbacks as well:

    1. Because, opposed to the MSDN way, I am using the DataContext it is no longer possible to select a text using the StaticResource reference dialog unless I setup a design time DataContext
    2. For the same reason the designer in Visual Studio does not show the text so the designer becomes pretty useless too.

    These are bad but I’ll try to fix them and will write a post on that when I find a solution.

    Next up: error messages. Silverlight applications usually handle logic asynchronously. This means that you’ll need a way of passing errors back to the UI thread and you’ll need to find a way of displaying them. I thought about this and figured that MessageBoxes wouldn’t do for me. When processing logic asynchronously and popping up a message box it probably will not be clear to the user where the error originated and the flow of the application will be disturbed too.

    Here is what I did to fix this in the ViewModel base class:

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Windows;
    
    namespace MVVM
    {
        public class ViewModelBase<T> : INotifyPropertyChanged
        {
            private Visibility _errorVisibility = Visibility.Collapsed;
            public Visibility ErrorVisibility
            {
                get
                {
                    return _errorVisibility;
                }
                private set
                {
                    if (_errorVisibility != value)
                    {
                        _errorVisibility = value;
                        OnPropertyChanged(&quot;ErrorVisibility&quot;);
                    }
                }
            }
    
            private string _errorMessage;
            public string ErrorMessage
            {
                get
                {
                    return _errorMessage;
                }
                set
                {
                    if (_errorMessage != value)
                    {
                        _errorMessage = value;
                        OnPropertyChanged(&quot;ErrorMessage&quot;);
                    }
                }
            }
    
            protected void ShowError(string errorMessage)
            {
                ErrorMessage = errorMessage;
                ErrorVisibility = Visibility.Visible;
            }
    
            public void ChangeLanguage(string language)
            {
                Example.Resources.Cultures.AppResources.Culture = new System.Globalization.CultureInfo(language);
                OnPropertyChanged(&quot;UITexts&quot;);
            }
    
            private static Example.Resources.Cultures.AppResources _uiTexts = new Resources.Cultures.AppResources();
    
            public Example.Resources.Cultures.AppResources UITexts
            {
                get
                {
                    return _uiTexts;
                }
            }
    
            public App Application
            {
                get
                {
                    return App.Current as App;
                }
            }
    
            #region INotifyPropertyChanged Implementation
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void NotifyPropertyChanged<TProperty>(
                Expression<Func<T, TProperty>> propertyExpression)
            {
                MemberExpression memberExpression = propertyExpression.Body
                    as System.Linq.Expressions.MemberExpression;
                if (memberExpression == null || (memberExpression != null &&
                    memberExpression.Member.MemberType != MemberTypes.Property))
                {
                    throw new ArgumentException(
                        &quot;The specified expression does not represent a valid property&quot;);
                }
                OnPropertyChanged(memberExpression.Member.Name);
            }
    
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler p = PropertyChanged;
                if (p != null)
                {
                    p(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }
    }
    

    The ShowError method is the method that a ViewModel would use to set an error. The View that is responsible for showing the message can simply bind to the properties ErrorMessage and ErrorVisibility like this:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height=&quot;auto&quot; />
        </Grid.RowDefinitions>
        <Rectangle Fill=&quot;{StaticResource PhoneAccentBrush}&quot;
                   Visibility=&quot;{Binding ErrorVisibility}&quot; />
        <TextBlock Margin=&quot;3&quot;
                   Text=&quot;{Binding ErrorMessage}&quot;
                   TextAlignment=&quot;Center&quot;
                   TextWrapping=&quot;Wrap&quot;
                   Foreground=&quot;White&quot;
                   Visibility=&quot;{Binding ErrorVisibility}&quot; />
    </Grid>
    

    The application heavily relies on a live connection to the web so notifying the user that the connection has been lost is needed in many places and again without hampering the user with modal boxes and breaking application flow. So I created a special sub class of the ViewModel base class that is connection aware:

    using System;
    using System.Net.NetworkInformation;
    using System.Windows;
    
    namespace MVVM
    {
        public class ConnectedViewModelBase<T> : ViewModelBase<T>
        {
            private bool _isDownloading = false;
            public bool IsDownloading
            {
                get
                {
                    return _isDownloading;
                }
                set
                {
                    if (_isDownloading != value)
                    {
                        _isDownloading = value;
                        OnPropertyChanged(&quot;IsDownloading&quot;);
                        OnPropertyChanged(&quot;DownloadVisibility&quot;);
                    }
                }
            }
    
            public Visibility DownloadVisibility
            {
                get
                {
                    return IsDownloading ? Visibility.Visible : Visibility.Collapsed;
                }
            }
    
            private int _downloadProgress;
            public int DownloadProgress
            {
                get
                {
                    return _downloadProgress;
                }
                set
                {
                    if (_downloadProgress != value)
                    {
                        _downloadProgress = value;
                        OnPropertyChanged(&quot;DownloadProgress&quot;);
                    }
                }
            }
    
            private Visibility disconnectedVisibility;
    
            public Visibility DisconnectedVisibility
            {
                get { return disconnectedVisibility; }
                set
                {
                    if (disconnectedVisibility != value)
                    {
                        disconnectedVisibility = value;
                        OnPropertyChanged(&quot;DisconnectedVisibility&quot;);
                    }
                }
            }
    
            public ConnectedViewModelBase()
            {
                NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
            }
    
            private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
            {
                UpdateNetworkStatus();
            }
    
            protected bool UpdateNetworkStatus()
            {
                var connected = NetworkInterface.GetIsNetworkAvailable();
                DisconnectedVisibility = connected ? Visibility.Collapsed : Visibility.Visible;
                return connected;
            }
        }
    }
    

    The property IsDownloading should be set by a ViewModel when it starts a request across the web. The Marketplace requires an application to be responsive and never have the user wait for more than 5 seconds. Because a download depends on&nbsp; network speed and available bandwidth a View can bind to DownloadVisibility and show a progress bar or give another visual clue. Similarly the View can bind to DownloadProgress to give the user more information on the download. the ViewModel will have to set the DownloadProgress propery.

    The view can bind to the DisconnectedVisibility property to indicate that the application has connection issues.

    These ViewModel base classes are still work in progress and they have only proved themselves in a single application.

    Share this

Erno de Weerd

View profile

Related IT training

Go to training website

Related Consultancy solutions

Go to infosupport.com

Related blogs

  • Innovative patterns in software quality management

    Innovative patterns in software quality management Tom van den Berg - 4 months ago

  • Developing a Service Fabric service using another host

    Developing a Service Fabric service using another host Tim van de Lockand - 8 months ago

  • Adding a package to your private WinGet.RestSource feed…

    Adding a package to your private WinGet.RestSource feed… Léon Bouquiet - 1 year ago

Related downloads

  • Beslisboom voor een rechtmatig ‘kopietje productie’

  • Klantreferentie: Remmicom zet wetgeving om in intellige…

  • Klantreferentie RDW: Samenwerken voor veilig en vertrou…

  • Klantreferentie BeFrank: Strategische IT voor een innov…

  • Wie durft te experimenteren met data in de zorg?

Related videos

  • mijnverzekeringenopeenrij.nl

    mijnverzekeringenopeenrij.nl

  • Winnaar | Innovation Projects 2017

    Winnaar | Innovation Projects 2017

  • Explore | Info Support & HAN & Poliskluis

    Explore | Info Support & HAN & Poliskluis

  • Info Support | Bedrijfsfilm

    Info Support | Bedrijfsfilm

  • LifeApps bij HagaZiekenhuis

    LifeApps bij HagaZiekenhuis

Nieuwsbrief

* verplichte velden

Contact

  • Head office NL
  • Kruisboog 42
  • 3905 TG Veenendaal
  • T +31 318 552020
  • Call
  • Mail
  • Directions
  • Head office BE
  • Generaal De Wittelaan 17
  • bus 30 2800 Mechelen
  • T +32 15 286370
  • Call
  • Mail
  • Directions

Follow us

  • Twitter
  • Facebook
  • Linkedin
  • Youtube

Newsletter

Sign in

Extra

  • Media Library
  • Disclaimer
  • Algemene voorwaarden
  • ISHBS Webmail
  • Extranet
Beheer cookie toestemming
Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
Functioneel
Altijd actief
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
Voorkeuren
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
Statistieken
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt. De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
Marketing
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
Beheer opties Beheer diensten Beheer leveranciers Lees meer over deze doeleinden
Voorkeuren
{title} {title} {title}