Daniel Vaughan

free range code

Geneva Developers Meetup Feb 2012

clock January 23, 2012 11:46 by author Daniel Vaughan

Live near the Geneva area of Switzerland? Feel like meeting up with other developers to discuss Microsoft software development, in particular Windows Phone, XAML, WinRT, Silverlight , WPF and ASP.NET? Come join us at the Microsoft building in Geneva on the 7th of February 2012.

Please let us know if you'll attend by adding your name to this poll

The location of the meeting is:

Microsoft Sàrl
MBC 12 ave. des Morgines 1213 Petit-Lancy, Geneva
View on Bing Maps 

Getting there:

• Public transport

    o From “Cornavin”, the main train station o Tram #14, direction “Bernex”

    o Get off at “Les Esserts” (15 min)

    o The “ave. des Morgines” is on the right o Walk 1 ½ block

• Car: there’re 2 supermarkets with parking nearby, but I don’t know if they close at night o “Migros”, rue des Bossons 78-80

    o Centre commercial de Lancy, route de Chancy 71

 

Once you’re in front of the building:

· Enter the front door

· Turn right

· Turn left just before the Atrium

· Take elevator E

· 3rd floor

· Turn left

 

The gates to the building close at 6.30 pm, so be sure to arrive before then.

Hope to see you there!



CodeProject Interview

clock September 29, 2011 10:53 by author Daniel Vaughan

Recently I took part in an interview with CodeProject. It includes some info about my background, projects, interests. 



Binding the WP7 ProgressIndicator in XAML

clock August 26, 2011 08:53 by author Daniel Vaughan

Update:

Since first posting this article, a later version of the WP FCL the ProgressIndicator gained binding support. You can bind it in a page like so:

<shell:SystemTray.ProgressIndicator>

        <shell:ProgressIndicator IsIndeterminate="{Binding Busy}" 

                                 IsVisible="{Binding Busy}" 

                                 Text="{Binding Message}" />

</shell:SystemTray.ProgressIndicator>

--------------------------------

 

The Mango beta of the Windows Phone 7 SDK sees the inclusion of a new way to display progress of asynchronous operations within the phone's system tray. This is done using the new ProgressIndicator class, which is a DependencyObject that hooks in to the native progress bar in the system tray, and allows you to display text message in the system tray, along with allowing you to control the progress bar that can handle both determinate and indeterminate states.

While the ProgressIndicator supports data-binding, the downside is that bindings need to be set up in the page code-beside; which is not very elegant. See the following example of a page constructor wiring up a ProgressIndicator:

 

public FooView()
{
    InitializeComponent();

    DataContext = new FooViewModel();

    Loaded += (o, args) =>
    {
        var progressIndicator = SystemTray.ProgressIndicator;

        if (progressIndicator != null)
        {
            return;
        }

        progressIndicator = new ProgressIndicator();

        SystemTray.SetProgressIndicator(this, progressIndicator);

        Binding binding = new Binding("Busy") { Source = ViewModel };

        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.IsVisibleProperty, binding);

        binding = new Binding("Busy") { Source = ViewModel };

        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.IsIndeterminateProperty, binding);

        binding = new Binding("Message") { Source = ViewModel };

        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.TextProperty, binding);
    };

}

 

While completing my latest chapter of Windows Phone 7 Unleashed, on local databases, I spent a few minutes writing a wrapper for the ProgressIndicator. The ProgressIndicatorProxy, as it's called, can be placed in XAML, and doesn't rely on any code-beside:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <u:ProgressIndicatorProxy IsIndeterminate="{Binding Indeterminate}" 
                                Text="{Binding Message}" 
                                Value="{Binding Progress}" />
</Grid>

 

The element itself has no visibility; its task is to attach a ProgressIndicator to the system tray, and to provide bindable properties that flow through to the ProgressIndicator instance.

When the element's Loaded event is raised, it instantiates a ProgressIndicator, assigns it to the system tray, and binds its properties to the ProgressIndicatorProxy objects properties. The class is shown in the following excerpt:

public class ProgressIndicatorProxy : FrameworkElement
{
    bool loaded;

    public ProgressIndicatorProxy()
    {
        Loaded += OnLoaded;
    }

    void OnLoaded(object sender, RoutedEventArgs e)
    {
        if (loaded)
        {
            return;
        }

        Attach();

        loaded = true;
    }

    public void Attach()
    {
        if (DesignerProperties.IsInDesignTool)
        {
            return;
        }

        var page = this.GetVisualAncestors<PhoneApplicationPage>().First();

        var progressIndicator = SystemTray.ProgressIndicator;
        if (progressIndicator != null)
        {
            return;
        }

        progressIndicator = new ProgressIndicator();

        SystemTray.SetProgressIndicator(page, progressIndicator);

        Binding binding = new Binding("IsIndeterminate") { Source = this };
        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.IsIndeterminateProperty, binding);

        binding = new Binding("IsVisible") { Source = this };
        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.IsVisibleProperty, binding);

        binding = new Binding("Text") { Source = this };
        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.TextProperty, binding);

        binding = new Binding("Value") { Source = this };
        BindingOperations.SetBinding(
            progressIndicator, ProgressIndicator.ValueProperty, binding);
    }

    #region IsIndeterminate

    public static readonly DependencyProperty IsIndeterminateProperty
        = DependencyProperty.RegisterAttached(
            "IsIndeterminate",
            typeof(bool),
            typeof(ProgressIndicatorProxy), new PropertyMetadata(false));

    public bool IsIndeterminate
    {
        get
        {
            return (bool)GetValue(IsIndeterminateProperty);
        }
        set
        {
            SetValue(IsIndeterminateProperty, value);
        }
    }

    #endregion

    #region IsVisible

    public static readonly DependencyProperty IsVisibleProperty
        = DependencyProperty.RegisterAttached(
            "IsVisible",
            typeof(bool),
            typeof(ProgressIndicatorProxy), new PropertyMetadata(true));

    public bool IsVisible
    {
        get
        {
            return (bool)GetValue(IsVisibleProperty);
        }
        set
        {
            SetValue(IsVisibleProperty, value);
        }
    }

    #endregion

    #region Text

    public static readonly DependencyProperty TextProperty
        = DependencyProperty.RegisterAttached(
            "Text",
            typeof(string),
            typeof(ProgressIndicatorProxy), new PropertyMetadata(string.Empty));

    public string Text
    {
        get
        {
            return (string)GetValue(TextProperty);
        }
        set
        {
            SetValue(TextProperty, value);
        }
    }

    #endregion

    #region Value

    public static readonly DependencyProperty ValueProperty
        = DependencyProperty.RegisterAttached(
            "Value",
            typeof(double),
            typeof(ProgressIndicatorProxy), new PropertyMetadata(0.0));

    public double Value
    {
        get
        {
            return (double)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
        }
    }

    #endregion
}

 

The sample code included with this post, contains a viewmodel with three properties, as listed:

  • Indeterminate, a Boolean that provides the IsIndeterminate value of the ProgressIndicator.
  • Progress: a double that is the source property of the Value property of the ProgressIndicator. This takes effect when the ProgressIndicator.IsIndeterminate property is true.
  • Message: a string value displayed via the ProgressIndicator.

The page is bound to an instance of the MainPageViewModel. The ProgressIndicatorProxy binds to the three viewmodel properties. In addition, a ToggleSwitch is used to control the indeterminate state of the ProgressIndicator via the Indeterminate property in the viewmodel, and a Slider controls the ProgressIndicator's Value property in the same manner. See the following excerpt:

<u:ProgressIndicatorProxy IsIndeterminate="{Binding Indeterminate}" 
                            Text="{Binding Message}" 
                            Value="{Binding Progress}" />

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel>
        <toolkit:ToggleSwitch 
            IsChecked="{Binding Indeterminate, Mode=TwoWay}" 
            Header="Indeterminate" />

        <Slider Value="{Binding Progress, Mode=TwoWay}"
                Maximum="1" LargeChange=".2" />
    </StackPanel>
</Grid>

 

The sample page is shown in Figure 1.

 

Progress indicator proxy screenshot

Figure 1: ProgressIndicator is controlled via a XAML binding.

 

Note that there is no requirement to use the MVVM infrastructure located in the sample. And that the ProgressIndicatorProxy is entirely independent. I will, however, be releasing Calcium for Windows Phone 7 soon, which contains a cavalcade of useful components for building MVVM apps for WP7.

The custom ProgressIndicatorProxy provides a simple way to harness the new ProgressIndicator from your XAML. I hope you find it useful.

ProgressIndicatorProxyExample.zip (767.78 kb)

 

If you are interested in up-to-the-minute WP7 info, check out the Windows Phone Experts group on LinkedIn.

 

Follow me on twitter

 



A Batch File for Closing Zune and Launching the WPConnect Tool

clock March 24, 2011 17:14 by author Daniel Vaughan

In a post from late last year, I looked at using a .bat file to detect the platform and launch the WPConnect tool using the path appropriate to the OS (32bit or 64 bit).

I've since updated the batch file, which now closes the Zune software, waits a few seconds, and then attempts to use the WPConnect tool. It's not rocket science, but it eases the burden a little when debugging on a Window Phone device.

I had hoped to be able to respond to stdout/err of the WPConnect executable. Seems I couldn't redirect the output to monitor it, and retry the connection if it failed. If you know a work-around, please let me know.

Anyway, without further ado, here's the new batch file.

If you'd prefer to copy and paste; the content of the file is as follows:

 

@ECHO OFF

ECHO (c) Daniel Vaughan 2011 http://danielvaughan.orpius.com

:LoopStart

SET %errorlevel% = 0

taskkill /IM zune.exe
ECHO Waiting for Zune to close...
@choice /T 15 /C y /CS /D y | REM

IF PROCESSOR_ARCHITECTURE == x86 (
    "%ProgramFiles%\Microsoft SDKs\Windows Phone\v7.0\Tools\WPConnect\WPConnect.exe"
) ELSE "%ProgramFiles(x86)%\Microsoft SDKs\Windows Phone\v7.0\Tools\WPConnect\WPConnect.exe"

@choice /T 5 /C y /CS /D y | REM

:LoopEnd

 

If you are interested in up-to-the-minute WP7 info, check out the Windows Phone Experts group on LinkedIn.

 

Follow me on twitter



Loading Data when the User Scrolls to the End of a List in Windows Phone 7

clock January 24, 2011 22:18 by author Daniel Vaughan

Most phone users are concerned about network usage. Network traffic comes at a premium, and a user's perception of the quality of your app depends a lot on its responsiveness. When it comes to fetching data from a network service, it should be done in the most efficient manner possible. Making the user wait while your app downloads giant reams of data doesn't cut it. It should, instead, be done in bite-sized chunks.

To make this easy for you, I have created a ScrollViewerMonitor which uses an attached property to monitor a ListBox and fetch data as the user needs it. It's as simple as adding an attached property to a control which contains a ScrollViewer, such as a ListBox, as shown in the following example:

<ListBox ItemsSource="{Binding Items}"
         u:ScrollViewerMonitor.AtEndCommand="{Binding FetchMoreDataCommand}" />

Notice the AtEndCommand. That's an attached property that allows you to specify a command to be executed when the user scrolls to the end of the list. Easy huh! I'll explain in a moment how this is accomplished, but first some background.

Background

For almost the last year, I've been building infrastructure for WP7 development. A lot has been going into the book I am writing, and even more is making its way into the upcoming Calcium for Windows Phone. I am pretty much at bursting point; wanting to get this stuff out there.

The chapter of Windows Phone 7 Unleashed, which discusses this code, demonstrates an Ebay search app that makes use of the Ebay OData feed (see Figure 1). It's simple, yet shows off some really nice techniques for handling asynchronous network calls.

Figure 1: The Ebay Seach app from Windows Phone 7 Unleashed.

 

The Ebay app isn't in the downloadable code for this post. But there is a simpler app that displays a list of numbers instead.

The way the ScrollViewerMonitor works is by retrieving the first child ScrollViewer control from its target (a ListBox in this case). It then listens to its VerticalOffset property for changes. When a change occurs, and the ScrollableHeight of the scrollViewer is the same as the VerticalOffset, the AtEndCommand is executed.

 

public class ScrollViewerMonitor
{
    public static DependencyProperty AtEndCommandProperty
        = DependencyProperty.RegisterAttached(
            "AtEndCommand"typeof(ICommand),
            typeof(ScrollViewerMonitor),
            new PropertyMetadata(OnAtEndCommandChanged));

    public static ICommand GetAtEndCommand(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(AtEndCommandProperty);
    }

    public static void SetAtEndCommand(DependencyObject obj, ICommand value)
    {
        obj.SetValue(AtEndCommandProperty, value);
    }


    public static void OnAtEndCommandChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)d;
        if (element != null)
        {
            element.Loaded -= element_Loaded;
            element.Loaded += element_Loaded;
        }
    }

    static void element_Loaded(object sender, RoutedEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)sender;
        element.Loaded -= element_Loaded;
        ScrollViewer scrollViewer = FindChildOfType<ScrollViewer>(element);
        if (scrollViewer == null)
        {
            throw new InvalidOperationException("ScrollViewer not found.");
        }

        var listener = new DependencyPropertyListener();
        listener.Changed
            += delegate
            {
                bool atBottom = scrollViewer.VerticalOffset
                                    >= scrollViewer.ScrollableHeight;

                if (atBottom)
                {
                    var atEnd = GetAtEndCommand(element);
                    if (atEnd != null)
                    {
            atEnd.Execute(null);
                    }                   
                }
            };
        Binding binding = new Binding("VerticalOffset") { Source = scrollViewer };
        listener.Attach(scrollViewer, binding);
    }

    static T FindChildOfType<T>(DependencyObject root) where T : class
    {
        var queue = new Queue<DependencyObject>();
        queue.Enqueue(root);

        while (queue.Count > 0)
        {
            DependencyObject current = queue.Dequeue();
            for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
            {
                var child = VisualTreeHelper.GetChild(current, i);
                var typedChild = child as T;
                if (typedChild != null)
                {
                    return typedChild;
                }
                queue.Enqueue(child);
            }
        }
        return null;
    }
}

 

Of course there is a little hocus pocus that goes on behind the scenes. The VerticalOffset property is a dependency property, and to monitor it for changes I've borrowed some of Pete Blois's code, which allows us to track any dependency property for changes. This class is called BindingListener and is in the downloadable sample code.

Sample Code

The ViewModel for the MainPage contains a FetchMoreDataCommand. When executed, this command sets a Busy flag, and waits a little while, then adds some more items to the ObservableCollection that the ListBox in the view is data-bound too.

Snippet

public class MainPageViewModel : INotifyPropertyChanged
{
    public MainPageViewModel()
    {
        AddMoreItems();

        fetchMoreDataCommand = new DelegateCommand(
            obj =>
                {
                    if (busy)
                    {
                        return;
                    }
                    Busy = true;
                    ThreadPool.QueueUserWorkItem(
                        delegate
                        {
                            /* This is just to demonstrate a slow operation. */
                            Thread.Sleep(3000);
                            /* We invoke back to the UI thread. 
                                * Ordinarily this would be done 
                                * by the Calcium infrastructure automatically. */
                            Deployment.Current.Dispatcher.BeginInvoke(
                                delegate
                                {
                                    AddMoreItems();
                                    Busy = false;
                                });
                        });
                    
            });
    }

    void AddMoreItems()
    {
        int start = items.Count;
        int end = start + 10;
        for (int i = start; i < end; i++)
        {
            items.Add("Item " + i);
        }
    }

    readonly DelegateCommand fetchMoreDataCommand;

    public ICommand FetchMoreDataCommand
    {
        get
        {
            return fetchMoreDataCommand;
        }
    }

    readonly ObservableCollection<string> items = new ObservableCollection<string>();

    public ObservableCollection<string> Items
    {
        get
        {
            return items;
        }
    }

    bool busy;

    public bool Busy
    {
        get
        {
            return busy;
        }
        set
        {
            if (busy == value)
            {
                return;
            }
            busy = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Busy"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var tempEvent = PropertyChanged;
        if (tempEvent != null)
        {
            tempEvent(this, e);
        }
    }
}

 

There's a lot more infrastructure provided with the book code. But I tried hard to slim everything down for this post. The MainPage.xaml contains a Grid with a ProgressBar, whose visbility depends on the Busy property of the viewmodel.

Snippet

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ListBox ItemsSource="{Binding Items}"
                u:ScrollViewerMonitor.AtEndCommand="{Binding FetchMoreDataCommand}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image Source="Images/WindowsPhoneExpertsLogo.jpg" 
                            Margin="10" />
                    <TextBlock Text="{Binding}" 
                                Style="{StaticResource PhoneTextTitle2Style}"/>                            
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Grid Grid.Row="1"
            Visibility="{Binding Busy, 
                Converter={StaticResource BooleanToVisibilityConverter}}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Text="Loading..." 
                    Style="{StaticResource LoadingStyle}"/>
        <ProgressBar IsIndeterminate="{Binding Busy}"
                        VerticalAlignment="Bottom"
                        Grid.Row="1" />
    </Grid>
</Grid>

 

You may be wondering why there is a databinding for ProgressBar's IsIndeterminate property. This is for performance reasons, as when indeterminate the ProgressBar is notorious for consuming CPU. Check out Jeff Wilcox's blog for a solution.

Now, when the user scrolls to the bottom of the list, the FetchMoreDataCommand is executed, providing an opportunity to call some network service asynchronously (see Figure 2).

 

 

Figure 2: Loading message is displayed when the user scrolls to the end of the list.

 

I hope you enjoyed this post, and that you find the attached code useful.

If you are interested in up-to-the-minute WP7 info, check out the Windows Phone Experts group on LinkedIn.

 

DanielVaughan.ScrollViewerMonitor.zip (126.56 kb)

 

Follow me on twitter



Calcium Downloads Surpass 10,000

clock January 12, 2011 12:30 by author Daniel Vaughan

Interest in the Calcium project has been huge this year. So much so that the number of downloads for Calcium has passed 10,000.

In the works for this year is a Windows Phone version of Calcium, which I have been implicitly working on during the writing of Windows Phone 7 Unleashed. I will also be improving support for the Silverlight for the desktop version of Calcium.

If you're a Calcium user, and have feature requests, be sure to add them to the tracker. I use that a lot to determine the priority of new features.



Refresh a WP7 PhoneApplicationPage

clock January 5, 2011 19:03 by author Daniel Vaughan

Here is a quick a dirty way to refresh a WP7 page. We use the NavigationService to navigate to the current page. There's a catch though (in fact there are two but we'll get to the second in a moment), we need to make a change to the Uri, else the NavigationService thinks we are trying to perform fragment navigation, which is not supported, and will raise an exception. A work-around is to tack a query string on the end, as shown in the following example:

 

void Button_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri(NavigationService.Source + "?Refresh=true"UriKind.Relative));
}

 

Keep in mind that this will cause the page to be placed on the history stack, which is not desirable as the hardware back button will cause the page to refresh, again.

Now the trouble with this approach, as Scott Cate points out, is that we end up having multiple query string parameters appended. Here is another approach that uses a counter:

 

static int refreshCount;

void Button_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine(NavigationService.Source);
string url = NavigationService.Source.ToString();

if (!url.Contains("RefreshCount="))
{
if (NavigationContext.QueryString.Count < 1)
{
url += "?RefreshCount=" + ++refreshCount;
}
else
{
url += "&RefreshCount=" + ++refreshCount;
}
}
else
{
url = Regex.Replace(url, @"RefreshCount=+\d""RefreshCount=" + ++refreshCount);
}
NavigationService.Navigate(new Uri(url, UriKind.Relative));
}

I don't particularly recommend refreshing a page. It would be best to replace the datacontext for a page. But if you absolutely must, there you have it.

 

 



CodeProject MVP 2011

clock January 4, 2011 11:02 by author Daniel Vaughan

I'm humbled to be re-awarded the status of CodeProject MVP for 2011. Considering that there are millions of Codeproject members, yet only 40 MVPs, it's a huge honour. Congratulations to my fellow awardess including Sacha Barber, Josh Smith, Pete O'Hanlon, and Michael Washington, and all of these great people:


 

Dalek Dave

Abhijit Jana

Abhishek Sur

Brij

Abhinav S

logicchild

Sandeep Mewara

Marcelo Ricardo de Oliveira

aspdotnetdev

Aescleal

OriginalGriff

William Winner

Kunal_Chowdhury

Alan Beasley

thatraja

Christ Kennedy

Al-Farooque Shubho

Henry Minute

Apriorit Inc

Sauro Viti

Arik Poznanski

Omar Al Zabir

Daniel Vaughan

Josh Smith

Pete O'Hanlon

John Simmons / outlaw programmer

Christian Graus

Mark Nischalke

«_Superman_»

Nishant Sivakumar

Shivprasad koirala

Md. Marufuzzaman

defwebserver

E.F. Nijboer

CPallini

Ajay Vijayvargiya

Dave Kreskowiak

Sacha Barber

Richard MacCutchan

Luc Pattyn

 



Custom Application Bar to Feature in Chapter

clock December 20, 2010 21:10 by author Daniel Vaughan

I've created a custom Windows Phone 7 application bar for a chapter entitled Taming the Application Bar. It supports data-binding, ICommands, button and menu item visibility, toggle buttons, and even multiple application bars for Pivots. 

I'll be releasing the source soon, and I'm really looking forward to getting it out there.

Windows Phone 7 Unleashed



Photo Location: a Windows Phone 7 Marketplace Application

clock November 19, 2010 19:50 by author Daniel Vaughan

 

Katka has just published a new application to the Windows Phone Marketplace. It's called Photo Location, and it allows you to visualise the geographical location of any photo that is stored on your phone. Here's the blurb:

You can browse through your photos on the Pictures Hub, and if you are ever wondering where a particular photo was taken, simply select Photo Location from the extras menu option in the application bar, and Photo Location will pinpoint the geographical location of your photo on the map. If you launch the application from the application list, Photo Location will take you directly to the Pictures Hub, where you can select any photo, and visualise where it was taken on a map. Not all photos will include GPS information, and Photo Location will only be able to show the location of photos that do include this information. The good news is, however, that the camera on your phone can be configured to include the location information whenever you take a photo, and is probably already setup to do so.

If you have the Zune software installed, you can take a look.

 

 

 



Order the Book

Ready to take your Windows Phone development skills to the next level? My book is the first comprehensive, start-to-finish developer's guide to Microsoft's Windows Phone 8. In it I teach through complete sample apps that illuminate each key concept with fully explained code and real-world context. Order Windows Phone 8 Unleashed

Windows Phone Experts Windows Phone Experts
LinkedIn Group

 

Bio

Daniel VaughanDaniel Vaughan is cofounder and president of Outcoder, a Swiss software and consulting company dedicated to creating best-of-breed user experiences and leading-edge back-end solutions, using the Microsoft stack of technologies--in particular Silverlight, WPF, WinRT, and Windows Phone.

He is a Microsoft MVP for Client Application Development, with more than a decade of commercial experience across a wide range of industries including finance, e-commerce, and multimedia.

Daniel is also the author of Windows Phone 7.5 Unleashed, the first comprehensive, start-to-finish developer's guide to Microsoft's Windows Phone 7.5.

Daniel is a Silverlight and WPF Insider, a member of the elite WPF Disciples group, and threetime CodeProject MVP.

Daniel is also the creator of a number of open-source projects, including Calcium, and Clog. E-mail me Send mail

 

Microsoft MVP logo Disciple
WPF and Silverlight Insiders
 

 

 

Sign in