Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Visual Studio Achievements for Windows Phone - Final notes before the beta

12.25.2011
| 2808 views |
  • submit to reddit

I finally got Visual Studio Achievements for Windows Phone to a beta stage. There is a lot of work that I am still doing, and you can see the planned roadmap here; however I decided to push a beta release in order to find existing issues while I am working on the rest of the additional application features.

Before releasing, I added some modifications to the code base, so the application doesn't freeze and I can bind to data in a much more efficient manner.

One of the major problems I had encountered during initial testing was the ability to bind data entries, when those are loaded dinamically (e.g from live tiles). Since the initial BindingPoint class version was implemented as a regular class with static properties, I was not able to directly implement INotifyPropertyChanged to notify the view about the changed values. To resolve the problem, I implemented the class in a form of a thread-safe singleton. Take a look at the modified BindingPoint class:

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

namespace VisualStudioAchievements
{
    public class BindingPoint : INotifyPropertyChanged
    {
        static BindingPoint instance = null;
        static readonly object padlock = new object();

        public BindingPoint()
        {
        }

        public static BindingPoint Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new BindingPoint();
                    }
                    return instance;
                }
            }
        }
        //Used for the PerformanceProgressBar element that is bound to it, to represent
        //whether the NinerReader request failed or not.
        private bool _hidePerfBar;
        public bool HidePerfBar
        {
            get
            {
                return _hidePerfBar;
            }
            set
            {
                if (_hidePerfBar != value)
                {
                    _hidePerfBar = value;
                    NotifyPropertyChanged("HidePerfBar");
                }
            }
        }

        public ObservableCollection<Niner> Niners { get; set; }

        private Niner _currentNiner;
        public Niner CurrentNiner
        {
            get
            {
                return _currentNiner;
            }
            set
            {
                if (_currentNiner != value)
                {
                    _currentNiner = value;
                    NotifyPropertyChanged("CurrentNiner");
                }
            }
        }

        private CompareNinerPair _comparedNiners;
        public CompareNinerPair ComparedNiners { 
            get
            {
                return _comparedNiners;
            }
            set
            {
                if (_comparedNiners != value)
                {
                    _comparedNiners = value;
                    NotifyPropertyChanged("ComparedNiners");
                }
            }
        }

        public ObservableCollection<CompareAchievementPair> ComparedAchievements { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                App.MainPageDispatcher.BeginInvoke(() => { PropertyChanged(this, new PropertyChangedEventArgs(info));});
            }
        }
    }
}

Another modification I implemented was supporting for the light theme. Matt "Roguecode" sent a report stating that the buttons and fields in critically-important pages were not visible when the light theme is selected. That was a critical issue that forced me to re-submit the initial beta entry, since there is a large group of users who have the light theme and will not be able to use the application. The fix was easy - modify parts of the XAML by using the first tip here. Instead of using hard-coded color values, I replaced some with pre-defined theme-dependent resources.

The NinerReader class now uses a safe-to-invoke Action<T> parameter instead of a custom delegate:

public void GetNiner(string name, bool isInit, Action<Niner> action = null)

With the delegate present, I would often get problems where the returned Niner was not passed correctly to the used instance. That way, I was getting duplicate user entries when none were needed. A relatively small fix that goes a long way:

reader.GetNiner(niner.Alias, true, extractedNiner =>
{
    BindingPoint.Instance.Niners.Add(extractedNiner);
});

Minor modifications include UI tuning, so now it is more organized:

That being said, the beta version is now available. As I am working on issues that are submitted as well as on additional features, you can download the latest source code here.