Visual Studio Achievements for Windows Phone - Final notes before the beta
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.





