Daniel Vaughan

free range code

Debugging the PhotoChooserTask and other Media Hub Related Tasks on WP7

clock November 14, 2010 15:56 by author Daniel Vaughan

Using the device debugger is a snap in Windows Phone 7. There are many benefits, and you can see your app executing in a real world environment, with most of the launchers and choosers available for testing. Some choosers, however, rely on the Windows Phone Media Hub; such as the PhotoChooserTask. Trying to debug across a call to that bad boy, with the Zune software running, will lock up your app.

Fortunately there's an easy to use tool that solves the problem by removing the need to have the Zune software running while debugging. It's called the Windows Phone Connect Tool. It was released as part of the recent update to the Windows Phone Developer Tools. This tool allows you to close the Zune software, after your phone device is connected; which means that choosers such as the PhotoChooserTask are able to function correctly while you are debugging.

There are a few steps to launching the tool. Opening a command prompt, navigating to a directory, launching the tool. So I've wrapped these steps up into a batch file which takes care of detecting the platform, locating the path to the WPConnect executable, and launching the tool. The steps for using the batch file are as follows:

  1. Connect your Windows Phone to your computer and ensure that it is detected by the Zune software.
  2. Close the Zune software after your Windows Phone is connected.
  3. Double click on the batch file.

Download it here (1 Kb) [Updated 24 Mar 2011)

Alternatively, to use the Windows Phone Connect Tool manually, follow these steps:

  1. Open a command prompt and navigate to the directory containing the Windows Phone Connect Tool (WPConnect.exe). The location of this file will be %ProgramFiles%\Microsoft SDKs\Windows Phone\v7.0\Tools\WPConnect.
  2. Connect your Windows Phone to your computer and ensure that it is detected by the Zune software.
  3. Close the Zune software after your Windows Phone is connected.
  4. At the command prompt, enter the command WPConnect.exe.


Work-Around for DataContractJsonSerializer ArgumentNullExceptions

clock October 25, 2010 00:50 by author Daniel Vaughan

If you've tried using a DataContractJsonSerializer or a DataContractSerializer with Push Notification for the Windows Phone, you may have experienced an ArgumentNullException during deserialization. This can happen because the MemoryStream is buffered with null characters '\0' that prevent deserialization. A solution is to create a new array and copy all bytes except for the trailing nulls, as shown in the following excerpt from the downloadable sample code in my upcoming book Windows Phone 7 Unleashed:

using (BinaryReader reader = new BinaryReader(bodyStream))
{
byte[] bodyBytes = reader.ReadBytes((int)bodyStream.Length);

int lengthWithoutNulls = bodyBytes.Length;
for (int i = bodyBytes.Length - 1; i >= 0 && bodyBytes[i] == '\0'
i--, lengthWithoutNulls--)
{
/* Intentionally left blank. */
}

byte[] cleanedBytes = new byte[lengthWithoutNulls];
Array.Copy(bodyBytes, cleanedBytes, lengthWithoutNulls);

DataContractJsonSerializer serializer
new DataContractJsonSerializer(typeof(StockQuote));

using (MemoryStream stream = new MemoryStream(cleanedBytes))
{
StockQuote = (StockQuote)serializer.ReadObject(stream);
}
}

Have a great day!

 



Windows Phone Developer Tools October 2010 Update

clock October 22, 2010 23:53 by author Daniel Vaughan

In case you haven't heard, there's an update for the Windows Phone Developer Tools that was released on 21 October (yesterday as I write this).

The Windows Phone Developer Tools October 2010 Update includes:

  • Windows Phone Capability Detection Tool – Detects the phone capabilities used by your application. When you submit your application to Windows Phone Marketplace , Microsoft performs a code analysis to detect the phone capabilities required by your application and then replaces the list of capabilities in the application manifest with the result of this detection process. This tool performs the same detection process and allows you to test your application using the same list of phone capabilities generated during the certification process. For more information, see How to: Use the Capability Detection Tool.
  • Windows Phone Connect Tool – Allows you to connect your phone to a PC when Zune® software is not running and debug applications that use media APIs. For more information, see How to: Use the Connect Tool.
  • Updated Bing Maps Silverlight Control – Includes improvements to gesture performance when using Bing™ Maps Silverlight® Control.

 

Download Page



Netflix WP7 Browser

clock October 15, 2010 21:19 by author Daniel Vaughan

 

 

Katka has published a great new article http://www.codeproject.com/KB/windows-phone-7/NetflixBrowser.aspx

Learn how to use the Pivot and Panorama controls, page navigation, OData and more!




Countdown to Global Silverlight Firestarter Event

clock October 15, 2010 17:11 by author Daniel Vaughan

Silverlight Firestarter is a one day global event, streamed live with Scott Guthrie and others. It will be held in Redmond on 2nd December 2010 from 8am to 5pm PST.

 

alt

 

The whole session will be conducted by Scott Guthrie, Jaime Rodriguez, Jesse Liberty, Pete Brown, John Papa, Tim Heuer, Mike Cook, and Jossef Goldberg. Join the session in-person or online, and learn more about Silverlight.

 

Here is the Agenda of the Event:

 

alt

 

When?

December 2, 2010 8am to 5pm PT

 

How much I have to pay for attending the Event?

It is a FREE Event. You don’t have to pay anything for it.

 

Register for the In-Person Event in Redmond

Register for the Online Event

 

Read more about it


Thanks to Fons Sonnemans for the gnarly timer.



Windows Phone Experts Group

clock September 14, 2010 18:30 by author Daniel Vaughan

 

There's a new group on LinkedIn: Windows Phone Experts

It's a group of professionals interested in delivering the next generation of rich mobile applications for the Windows Phone platform.



ReaderWriterLockSlim: Conquering Mismatched Enter and Exit Calls

clock August 14, 2010 13:43 by author Daniel Vaughan

The ReaderWriterLockSlim class is used to protect a resource that is read by multiple threads and written to by one thread at a time. The class exists in the desktop FCL, but is noticeably absent from the Silverlight FCL. To readily support both platforms, some time ago, I incorporated the open-source mono implementation of the ReaderWriterLockSlim class into the Silverlight version of my core library, which is downloadable from http://calcium.codeplex.com/SourceControl/list/changesets

ReaderWriterLockSlim is a light-weight alternative to the Monitor class, for providing for concurrency. I say light-weight because the Monitor class only provides for exclusive access; where only a single thread can enter, regardless of the kind of operation.

The Monitor class, however, has an advantage: its syntax can be simplified using the lock statement, as shown in the following code snippet:

System.Object resourceLock = new System.Object();
System.Threading.Monitor.Enter(resourceLock);
try
{
DoSomething();
}
finally
{
System.Threading.Monitor.Exit(resourceLock);
}

 

Which is equivalent to the following, when using a lock statement:

lock (x)
{
DoSomething();
}

 

Using the lock statement means that we never get caught out forgetting to exit the lock, which could lead to a thread being blocked indefinitely.

No such baked-in infrastructure exists for the ReaderWriterLockSlim. So, I've created a number of extension methods to simulate the lock statement for the ReaderWriterLockSlim.

Using Extension Methods to Simulate Lock Syntax

If you've used the ReaderWriterLockSlim a lot, you'll know that mismatching Enter and Exit calls can be easy to do, especially when pasting code. For example, in the following excerpt we see how a call to enter a write protected section of code is mismatched with a call to exit a read section:

ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim();

try
{
lockSlim.EnterWriteLock();
DoSomething();
}
finally
{
lockSlim.ExitReadLock();
}

 

This code will result in a System.Threading. SynchronizationLockException being raised.

The extension methods that have been written, allow a Func or an Action to be supplied, which will be performed within a try/finally block. The previous excerpt can be rewritten more concisely as:

ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim();
lockSlim.PerformUsingWriteLock(() => DoSomething);

 

In the downloadable code I have included a unit test to demonstrate how the ReaderWriterLockSlim extension methods are used, (see Listing 1).

Listing 1: LockSlimTests Class

[TestClass]
public class LockSlimTests : SilverlightTest
{
readonly static List<string> sharedList = new List<string>();

[TestMethod]
public void ExtensionsShouldPerformActions()
{
ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim();

string item1 = "test";

// Rather than this code:
// try
// {
// lockSlim.EnterWriteLock();
// sharedList.Add(item1);
// }
// finally
// {
// lockSlim.ExitWriteLock();
// }
// We can write this one liner:
lockSlim.PerformUsingWriteLock(() => sharedList.Add(item1));

// Rather than this code:
// string result;
// try
// {
// lockSlim.EnterReadLock();
// result = sharedList[0];
// }
// finally
// {
// lockSlim.ExitReadLock();
// }
// We can write this one liner:
string result = lockSlim.PerformUsingReadLock(() => sharedList[0]);

Assert.AreEqual(item1, result);

string item2 = "test2";

// Rather than this code:
// try
// {
// lockSlim.EnterUpgradeableReadLock();
// if (!sharedList.Contains(item2))
// {
// try
// {
// lockSlim.EnterWriteLock();
// sharedList.Add(item2);
// }
// finally
// {
// lockSlim.ExitWriteLock();
// }
// }
// }
// finally
// {
// lockSlim.ExitUpgradeableReadLock();
// }
// We can write this:
lockSlim.PerformUsingUpgradeableReadLock(() =>
{
if (!sharedList.Contains(item2))
{
lockSlim.PerformUsingWriteLock(() => sharedList.Add(item2));
}
});

// Rather than this code:
// try
// {
// lockSlim.EnterReadLock();
// result = sharedList[1];
// }
// finally
// {
// lockSlim.ExitReadLock();
// }
// We can write this:
result = lockSlim.PerformUsingReadLock(() => sharedList[1]);

Assert.AreEqual(item2, result);
}

}

 

The result of executing this test is shown in Figure 1.

 

Figure 1: Result of running the ReaderWriterLockSlimExtension tests.

 

The ReaderWriterLockSlimExtensions accept a simple Action or a Func to return value, and take care of calling the appropriate Enter and Exit methods, inside a try/finally block, (see Listing 2).

Listing 2: ReaderWriterLockSlimExtensions Class

public static class ReaderWriterLockSlimExtensions
{
public static void PerformUsingReadLock(this ReaderWriterLockSlim readerWriterLockSlim, Action action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterReadLock();
action();
}
finally
{
readerWriterLockSlim.ExitReadLock();
}
}

public static T PerformUsingReadLock<T>(this ReaderWriterLockSlim readerWriterLockSlim, Func<T> action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterReadLock();
return action();
}
finally
{
readerWriterLockSlim.ExitReadLock();
}
}

public static void PerformUsingWriteLock(this ReaderWriterLockSlim readerWriterLockSlim, Action action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterWriteLock();
action();
}
finally
{
readerWriterLockSlim.ExitWriteLock();
}
}

public static T PerformUsingWriteLock<T>(this ReaderWriterLockSlim readerWriterLockSlim, Func<T> action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterWriteLock();
return action();
}
finally
{
readerWriterLockSlim.ExitWriteLock();
}
}

public static void PerformUsingUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLockSlim, Action action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterUpgradeableReadLock();
action();
}
finally
{
readerWriterLockSlim.ExitUpgradeableReadLock();
}
}

public static T PerformUsingUpgradeableReadLock<T>(this ReaderWriterLockSlim readerWriterLockSlim, Func<T> action)
{
ArgumentValidator.AssertNotNull(readerWriterLockSlim, "readerWriterLockSlim");
ArgumentValidator.AssertNotNull(action, "action");
try
{
readerWriterLockSlim.EnterUpgradeableReadLock();
return action();
}
finally
{
readerWriterLockSlim.ExitUpgradeableReadLock();
}
}
}

 

The ArgumentValidator class is present in my base library. Calls to its AssertNotNull can be replaced with a null check, and if null throw an ArgumentNullException. If you'd like the code for the ArgumentValidator etc., you can find it in the Core class library in the source available at http://calcium.codeplex.com/SourceControl/list/changesets

Conclusion

In this post we have seen how extension methods can be used to ensure that the ReaderWriterLockSlim class is correctly exited after a thread critical region. This avoids the problem of mismatched Enter and Exit calls, which can result in exceptions and indefinite blocking.

I hope you have enjoyed this post, and that you find the code and ideas presented within it useful.

 

Download code: ReaderWriterLockSlimExtensions.zip (1.14 mb)



Enforcing Single Instance WPF Applications

clock August 1, 2010 17:39 by author Daniel Vaughan

Introduction

Today the WPF Disciples, and in particular my good friend and fellow WPF Disciple, Pete O'Hanlon, were sitting around the proverbial campfire, discussing how to enforce single instance WPF apps, for Pete's cool Goldlight project. By single instance WPF apps, I mean limiting an executable to only one instance in execution. This can be useful in scenarios where multiple application instances may play havoc with shared state. I took some time away from writing my book, to see if I could come up with something usable.

Building a Single Instance Application Enforcer

The singleton application model works like this:

  1. User starts app1.
  2. User starts app2.
  3. App2 detects app1 is running.
  4. App2 quits.

 

There is, however, a second part to our challenge, as Pete pointed out. What happens if we wish to pass some information from app2 to app1 before app2 quits? If, for example, the application is associated with a particular file type, and the user happens to double click on a file of that type, then we would have app2 tell app1 what file the user was trying to open.

To accomplish this we need a means to communicate between the two application instances. There are a number of approaches that could be taken, and some include:

  • Named pipes
  • Sending a message to the main application's window with a native API call
  • MemoryMappedFile

I chose to go for the MemoryMappedFile, along with an EventWaitHandle. The consensus by the Disciples was for a Mutex (not an EventWaitHandle), but the Mutex turned out not to provide for the initial signaling that I needed. I have encapsulated the logic for the singleton application enforcement, into a class called SingletonApplicationEnforcer (see Listing 1). The class instantiates the EventWaitHandle, and informs the garbage collector via the GC.KeepAlive method, that it should not be garbage collected. If this is the only application that has instantiated the EventWaitHandle with the specified name, then the createdNew argument will be set to true. This is how we determine, if the application is the singleton application.

Listing 1: SingletonApplicationEnforcer Class

/// <summary>
/// This class allows restricting the number of executables in execution, to one.
/// </summary>
public sealed class SingletonApplicationEnforcer
{
    readonly Action<IEnumerable<string>> processArgsFunc;
    readonly string applicationId;
    Thread thread;
    string argDelimiter = "_;;_";

    /// <summary>
    /// Gets or sets the string that is used to join 
    /// the string array of arguments in memory.
    /// </summary>
    /// <value>The arg delimeter.</value>
    public string ArgDelimeter
    {
        get
        {
            return argDelimiter;
        }
        set
        {
            argDelimiter = value;
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="SingletonApplicationEnforcer"/> class.
    /// </summary>
    /// <param name="processArgsFunc">A handler for processing command line args 
    /// when they are received from another application instance.</param>
    /// <param name="applicationId">The application id used 
    /// for naming the <seealso cref="EventWaitHandle"/>.</param>
    public SingletonApplicationEnforcer(Action<IEnumerable<string>> processArgsFunc, 
        string applicationId = "DisciplesRock")
    {
        if (processArgsFunc == null)
        {
            throw new ArgumentNullException("processArgsFunc");
        }
        this.processArgsFunc = processArgsFunc;
        this.applicationId = applicationId;
    }

    /// <summary>
    /// Determines if this application instance is not the singleton instance.
    /// If this application is not the singleton, then it should exit.
    /// </summary>
    /// <returns><c>true</c> if the application should shutdown, 
    /// otherwise <c>false</c>.</returns>
    public bool ShouldApplicationExit()
    {
        bool createdNew;
        string argsWaitHandleName = "ArgsWaitHandle_" + applicationId;
        string memoryFileName = "ArgFile_" + applicationId;

        EventWaitHandle argsWaitHandle = new EventWaitHandle(
            false, EventResetMode.AutoReset, argsWaitHandleName, out createdNew);

        GC.KeepAlive(argsWaitHandle);

        if (createdNew)
        {
            /* This is the main, or singleton application. 
                * A thread is created to service the MemoryMappedFile. 
                * We repeatedly examine this file each time the argsWaitHandle 
                * is Set by a non-singleton application instance. */
            thread = new Thread(() =>
                {
                    try
                    {
                        using (MemoryMappedFile file = MemoryMappedFile.CreateOrOpen(memoryFileName, 10000))
                        {
                            while (true)
                            {
                                argsWaitHandle.WaitOne();
                                using (MemoryMappedViewStream stream = file.CreateViewStream())
                                {
                                    var reader = new BinaryReader(stream);
                                    string args;
                                    try
                                    {
                                        args = reader.ReadString();
                                    }
                                    catch (Exception ex)
                                    {
                                        Debug.WriteLine("Unable to retrieve string. " + ex);
                                        continue;
                                    }
                                    string[] argsSplit = args.Split(new string[] { argDelimiter }, 
                                                                    StringSplitOptions.RemoveEmptyEntries);
                                    processArgsFunc(argsSplit);
                                }

                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Unable to monitor memory file. " + ex);
                    }
                });

            thread.IsBackground = true;
            thread.Start();
        }
        else
        {
            /* Non singleton application instance. 
                * Should exit, after passing command line args to singleton process, 
                * via the MemoryMappedFile. */
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(memoryFileName))
            {
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    var writer = new BinaryWriter(stream);
                    string[] args = Environment.GetCommandLineArgs();
                    string joined = string.Join(argDelimiter, args);
                    writer.Write(joined);
                }
            }
            argsWaitHandle.Set();
        }

        return !createdNew;
    }
}

If the process happens to be the singleton application, then a new thread is started that will block until it receives a signal (via the argsWaitHandle). This signal indicates that the MemoryMappedFile contains data to be read. It is non-singleton applications instances that perform this signalling, via the argsWaitHandle.Set method, after the string arguments have been written to the MemoryMappedFile.

Demonstrating the SingletonApplicationEnforcer Class

The downloadable code includes two solutions, and two projects. Each use the SingletonApplicationEnforcer class in their respective App (App.xaml.cs) classes. To try out the sample, open both solutions. Start debuging the SingleApp project first, and then launch the SingleApp2 project. What will hopefully result is that the SingleApp2 project will detect that it is not the singleton application, and it will write its command line arguments to a MemoryMappedFile. The SingleApp application will detect that data has been written to the file, and present the command line arguments in its main window (see Figure 1).

Figure 1: The demo application consists of a single window, which displays received command line arguments.

 

The entry point for either projects is the App class. It is in this class that we consume the SingletonApplicationEnforcer class, to detect whether the application should be allowed to execute (see Listing 2). The App classes constructor uses the SingletonApplicationEnforcer's ShouldApplicationExit method; which, as we saw in Listing 1, uses an EventWaitHandle to determine if it is the only instance in execution. If it isn't then the method returns true, and the application is explicitly shutdown.

Listing 2: App Class

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    readonly SingletonApplicationEnforcer enforcer = new SingletonApplicationEnforcer(DisplayArgs);

    public App()
    {
        if (enforcer.ShouldApplicationExit())
        {
            this.Shutdown();
        }
    }

    public static void DisplayArgs(IEnumerable<string> args)
    {
        foreach (var arg in args)
        {
            string message = string.Format("Received arg: {0}", arg);
            Debug.WriteLine(message);
        }
            
        var dispatcher = Current.Dispatcher;
        if (dispatcher.CheckAccess())
        {
            ShowArgs(args);
        }
        else
        {
            dispatcher.BeginInvoke(
                new Action(delegate
                {
                    ShowArgs(args);
                }));
        }
    }

    static void ShowArgs(IEnumerable<string> args)
    {
        var mainWindow = Current.MainWindow as MainWindow;
        if (mainWindow != null && args != null)
        {
            foreach (var arg in args)
            {
                mainWindow.ViewModel.Args.Add(arg);
            }
        }
    }

}

As usual, this application uses the MVVM pattern. The MainWindow has its DataContext property set to an instance of the MainWindowViewModel (see Listing 3).

Listing 3: MainWindow XAML

<Window x:Class="SingleApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Singleton Application Enforcer Example" 
        Height="350" Width="525" ResizeMode="NoResize" Background="Black">
    <StackPanel>
        <Image Source="Images/DisciplesBackground.jpg" />
        <StackPanel Margin="10">
            <TextBlock Text="Received Args:" FontSize="16" Padding="10" Foreground="White"/>
            <ListBox ItemsSource="{Binding Args}" 
                     VerticalAlignment="Stretch" Height="185" />
        </StackPanel>
    </StackPanel>
</Window>

The viewmodel (MainWindowViewModel), shown in Listing 2, exposes an ObsertableCollection of strings, that reflect arguments that are passed to the application, from other application instances.

Listing 4: MainWindowViewModel

public class MainWindowViewModel : INotifyPropertyChanged
{
    static ObservableCollection<string> args = new ObservableCollection<string>();

    public ObservableCollection<string> Args
    {
        get
        {
            return args;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


Conclusion

In this post we have seen how a MemoryMappedFile can be used in conjunction with a EventWaitHandle, to provide for cross process communication in order to limit execution to a single application instance. We also saw how to communicate command line arguments to the singleton application, so that it can respond adequately to user intent.

I hope you enjoyed this post, and that you find the code and ideas presented here useful.

Download code: SingletonEnforcementV2.zip (345.05 kb)



Writing Windows Phone 7 Unleashed

clock July 28, 2010 13:21 by author Daniel Vaughan

For the last couple of months I've had my head down writing a WP7 book. Entitled Windows Phone 7 Unleashed, it will be published though Sams Publishing. I'm pouring lots of tips and techniques into this book, along with the requisite WP7 development info. The book will lead you through end to end production of WP7 apps, from developing Silverlight and XNA apps, through to certification and publishing on the Windows Phone Marketplace.

Figure 1: Windows Phone 7 Unleashed cover (may change)

There are also many sample applications for just about all the main topics. One such sample, in the chapter on Push Notification, demonstrates toast, tile, and raw push notifications using a stock ticker app. It allows you to register to receive stock price updates, for a particular stock symbol, via a cloud service. The cloud service periodically sends real stock prices to the device, as you can see in the following screen shots.

 

Figure 2: Raw notifications are received in the Stock Quoter screen. Figure 3: Toast and tile notification are received showing updated stock market quotes.

 

It's just one of many apps in the book.

I'm very excited about WP7. I really like the simplicity of the geo location API, and how social networking is integrated into the OS. There are many reasons why WP7 will transform mobile development. I still have a long road ahead of me with the writing of the book. I'll be posting more about phone development in the coming months.

 



Introducing the Model Thread View Thread Pattern

clock May 1, 2010 13:09 by author Daniel Vaughan

Reduce threading code, and increase UI responsiveness with a new pattern extending MVVM. The article describes an approach that leverages the facilities that make MVVM so effective. The MTVT pattern is an architectural pattern used for explicit demarcation of the view and view model via disparate threads of execution.

Read more




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