<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9 - Entries tagged with XAML</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/xaml/RSS"/>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9 - Entries tagged with XAML</title>
      <link>http://channel9.msdn.com/Tags/xaml</link>
    </image>
    <itunes:image href=""/>
    <itunes:category text="Technology"/>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Tags/xaml</link>
    <language>en</language>
    <pubDate>Sun, 12 Feb 2012 10:56:54 GMT</pubDate>
    <lastBuildDate>Sun, 12 Feb 2012 10:56:54 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>26</c9:totalResults>
    <c9:pageCount>2</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Currency Converter v2 – Now on Caffeine!</title>
      <description><![CDATA[ <p>Taking user feedback about the application into consideration, it’s time to make some improvements! J</p><p>Here are some of the reports we got from the users:</p><ul><li>The application is too slow when exchanging currencies </li><li>It uses too much data traffic/should cache the exchange rates </li><li>It doesn’t work for some currencies </li><li>The results are inaccurate/using out-of-date exchange rates </li></ul><p>So, what we can see from these comments is that we need a better data source, and that we should use some sort of caching mechanism…</p><p>I think I’ll go ahead and put some coffee on to boil!</p><h3>To Bing or not to Bing…</h3><p>The first version of Currency Converter used Bing to make the exchanges, which resulted in some of the reports you read above!</p><p>For this version, however, we decided to use MSN Money because it has more accurate and up-to-date data, and because it works every time no matter the currency!</p><p>MSN Money provides a very nice page on which we can see current currency exchange rates in relation to US Dollars; just open your Internet Explorer 8.0&#43; and navigate to the following URL:</p><p><a href="http://moneycentral.msn.com/investor/market/exchangerates.aspx">http://moneycentral.msn.com/investor/market/exchangerates.aspx</a></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D.png" alt="image" width="589" height="442" border="0"></a></p><p>As you can see here, we have all the data we need to convert from X to USD and from USD to X, and we can even convert from X to USD to Y.</p><p>So, why not just get all of this data on a single request, cache it, and use it offline to make the currency exchanges? J</p><p>Like before, we will retrieve the data we require from the page HTML by using Regular Expressions. To do so, open Internet Explorer Developer Tools (press F12), use the “Select element by click” option (Ctrl &#43; B), and click on the “Argentine Peso” text; you’ll get something looking like this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B10%5D.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B6%5D.png" alt="image" width="589" height="442" border="0"></a></p><p>Using the information above, we can see a pattern in the code:</p><p><strong>HTML<br></strong><pre class="brush: html">&lt;tr&gt;
    &lt;td&gt;CURRENCY&lt;/td&gt;
    &lt;td style=”text-align:right”&gt;&lt;a SOMETHING&gt;VALUE_IN_USD&lt;/a&gt;&lt;/td&gt;
    &lt;td style=”text-align:right”&gt;&lt;a SOMETHING&gt;VALUE_PER_USD&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;</pre></p><p>Now that we know the pattern, we are now able to build this regular expression:</p><p><strong>C#<br></strong><pre class="brush: csharp">private static Regex _resultRegex = 
    new Regex(&quot;&lt;tr&gt;&lt;td&gt;(?&lt;currency&gt;[^&lt;&gt;]&#43;)&lt;/td&gt;&lt;td style=&quot;&quot;text-align:right&quot;&quot;&gt;.*?&gt;(?&lt;value&gt;[0-9.,]&#43;)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&quot;);</pre></p><p>Applying this Regular Expression to the retrieved HTML will allows us to get every row matching it, and retrieve the Currency Name and the “Per USD” Exchange Rate!</p><h3>Time for some coding</h3><p>Now that we know how to get all the currency rates from a single URL, it’s time to make the necessary changes to our code to accommodate the new data!</p><p>Like the previous article, we will maintain the MVVM pattern, showing the coding from the pattern’s bottom (Model) to the very top (View).</p><h4>The (Re)Model</h4><p>Here are the changes we need to make on our model in order to accommodate the retrieved and cached currency rates:</p><ul><li>Set each currency to save its exchange rate and last update </li><li>Mark the base currency (US Dollar), giving it an exchange rate of 1.0 (trying to convert from USD to USD? Right…) </li><li>Add an “Update Exchange Rates” operation to the service </li></ul><p>And here is the full Model, with the changes in yellow:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B13%5D.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B7%5D.png" alt="image" width="547" height="402" border="0"></a></p><p><strong>C#<br></strong><pre class="brush: csharp">using System;public interface ICurrencyExchangeService
{
    ICurrency[] Currencies { get; }    ICurrency BaseCurrency { get; }    void ExchangeCurrency(double amount, ICurrency fromCurrency, ICurrency toCurrency, Action&lt;ICurrencyExchangeResult&gt; callback);    void UpdateCachedExchangeRates(Action&lt;CachedExchangeRatesUpdateResult&gt; callback, object state);
}public interface ICurrency
{
    string Name { get; }    double CachedExchangeRate { get; set; }    DateTime CachedExchangeRateUpdatedOn { get; set; }
}public interface ICurrencyExchangeResult
{
    Exception Error { get; }    string ExchangedCurrency { get; }    double ExchangedAmount { get; }
}public interface ICachedExchangeRatesUpdateResult
{
    Exception Error { get; }    object State { get; }
}</pre></p><p>The ICurrencyExchangeService now has a new BaseCurrency property that we will set with the “US Dollar” currency instance, as well as an UpdateCachedExchangeRates method to update all the exchange rates.</p><p>For the ICurrency, we have two new properties: the CachedExchangeRate to store the currency exchange rate value, and the CachedExchangeRateUpdatedOn for the last update date.</p><p>A new interface called ICachedExchangeRatesUpdateResult has been added in order to return any exception thrown by the ICurrencyExchangeService.UpdateCachedExchangeRates method asynchronous execution to the caller.</p><p>Now let’s look at the interface’s implementation:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B16%5D.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B8%5D.png" alt="image" width="589" height="392" border="0"></a></p><p>The first new thing to take note of is that we now have a CurrencyBase abstract class. From here, we extend the MsnMoneyCurrency class, adding a single Id property to store the numeric Id for the Currency found in MSN Money.</p><p>Next is the MsnMoneyV2CurrencyExchangeService, a direct implementation of the ICurrencyExchangeService.</p><p>Unlike BingCurrencyExchangeService from the previous version, notice that MsnMoneyV2CurrencyExchangeService does not extend the CurrencyExchangeServiceBase, and that it only requests online data in the UpdateCachedExchangeRates method and not on every ExchangeCurrency method call.</p><p>Here is the code for these classes:</p><p><strong>C#<br></strong><pre class="brush: csharp">public class MsnMoneyV2CurrencyExchangeService : ICurrencyExchangeService
{
    private const string MsnMoneyUrl = &quot;<a href="http://moneycentral.msn.com/investor/market/exchangerates.aspx?selRegion=1&amp;selCurrency=1&quot;;">http://moneycentral.msn.com/investor/market/exchangerates.aspx?selRegion=1&amp;selCurrency=1&quot;;</a>    #region Static Globals    private static Regex _resultRegex = new Regex(@&quot;&lt;tr&gt;&lt;td&gt;(?&lt;currency&gt;[^&lt;&gt;]&#43;)&lt;/td&gt;&lt;td style=&quot;&quot;text-align:right&quot;&quot;&gt;.*?&gt;(?&lt;value&gt;[0-9.,]&#43;)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&quot;);    private static ICurrency[] _currencies = new ICurrency[] { 
        //The currencies exposed by MSN Money will go here
    };    #endregion    #region Properties    public ICurrency[] Currencies
    {
        get
        {
            return _currencies;
        }
    }    public ICurrency BaseCurrency { get; protected set; }    #endregion    public MsnMoneyV2CurrencyExchangeService()
    {
        BaseCurrency = Currencies.First(x =&gt; x.Name == &quot;US Dollar&quot;);
    }    public void ExchangeCurrency(double amount, ICurrency fromCurrency, ICurrency toCurrency, bool useCachedExchangeRates, Action&lt;ICurrencyExchangeResult&gt; callback, object state)
    {
        if (useCachedExchangeRates)
        {
            try
            {
                ExchangeCurrency(amount, fromCurrency, toCurrency, callback, state);                return;
            }
            catch
            {
            }
        }        UpdateCachedExchangeRates(result =&gt;
        {
            if (result.Error != null)
            {
                callback(new CurrencyExchangeResult(result.Error, state));                return;
            }            try
            {
                ExchangeCurrency(amount, fromCurrency, toCurrency, callback, state);
            }
            catch (Exception ex)
            {
                callback(new CurrencyExchangeResult(ex, state));
            }
        }, state);
    }    private void ExchangeCurrency(double amount, ICurrency fromCurrency, ICurrency toCurrency, Action&lt;ICurrencyExchangeResult&gt; callback, object state)
    {
        var fromExchangeRate = fromCurrency.CachedExchangeRate;
        var toExchangeRate = toCurrency.CachedExchangeRate;
        var timestamp = DateTime.Now;        if (fromCurrency == BaseCurrency)
            fromExchangeRate = 1.0;
        else
        {
            if (timestamp &gt; fromCurrency.CachedExchangeRateUpdatedOn)
                timestamp = fromCurrency.CachedExchangeRateUpdatedOn;
        }        if (toCurrency == BaseCurrency)
            toExchangeRate = 1.0;
        else
        {
            if (timestamp &gt; toCurrency.CachedExchangeRateUpdatedOn)
                timestamp = toCurrency.CachedExchangeRateUpdatedOn;
        }        if (fromExchangeRate &gt; 0 &amp;&amp; toExchangeRate &gt; 0)
        {
            var exchangedAmount = amount / fromExchangeRate * toExchangeRate;            callback(new CurrencyExchangeResult(toCurrency, exchangedAmount, timestamp, state));
        }
        else
            throw new Exception(&quot;Conversion not returned!&quot;);
    }    public void UpdateCachedExchangeRates(Action&lt;CachedExchangeRatesUpdateResult&gt; callback, object state)
    {
        var request = HttpWebRequest.Create(MsnMoneyUrl);        request.BeginGetResponse(ar =&gt;
        {
            try
            {
                var response = (HttpWebResponse)request.EndGetResponse(ar);                if (response.StatusCode == HttpStatusCode.OK)
                {
                    string responseContent;                    using (var streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        responseContent = streamReader.ReadToEnd();
                    }                    foreach (var match in _resultRegex.Matches(responseContent).Cast&lt;Match&gt;())
                    {
                        var currencyName = match.Groups[&quot;currency&quot;].Value.Trim();                        var currency = Currencies.FirstOrDefault(x =&gt; string.Compare(x.Name, currencyName, StringComparison.InvariantCultureIgnoreCase) == 0);                        if (currency != null)
                        {
                            currency.CachedExchangeRate = double.Parse(match.Groups[&quot;value&quot;].Value, CultureInfo.InvariantCulture);
                            currency.CachedExchangeRateUpdatedOn = DateTime.Now;
                        }
                    }                    callback(new CachedExchangeRatesUpdateResult(ar.AsyncState));
                }
                else
                {
                    throw new Exception(string.Format(&quot;Http Error: ({0}) {1}&quot;,
                        response.StatusCode,
                        response.StatusDescription));
                }
            }
            catch (Exception ex)
            {
                callback(new CachedExchangeRatesUpdateResult(ex, ar.AsyncState));
            }
        }, state);
    }
}</pre></p><p>Here’s how it works: when the ExchangeCurrency method is called, we pass a parameter (useCachedExchangeRates) that instructs the method to use (or not!) the previously cached exchange rates.</p><p>Next, make the exchange operation and return the results. If the operation throws an exception, or if we didn’t allow for cached exchange rates usage, call the UpdateCachedExchangeRates to update the exchange rates and then run the exchange operation with the new data.</p><p>And that’s about it for the Model!</p><h4>The ViewModel</h4><p>We maintained the full ViewModel from the previous version, but added some new functionality to it. Here’s the coding (main changes are in yellow):</p><p><strong>C#<br></strong><pre class="brush: csharp">public class MainViewModel : INotifyPropertyChanged
{
    //Full previous code    #region Properties    [IgnoreDataMember]
    public ICurrencyExchangeResult Result
    {
        get
        {
            return _result;
        }
        protected set
        {
            if (_result == value)
                return;            _result = value;            RaisePropertyChanged(&quot;Result&quot;);
            RaisePropertyChanged(&quot;ExchangedCurrency&quot;);
            RaisePropertyChanged(&quot;ExchangedAmount&quot;);
            RaisePropertyChanged(&quot;ExchangedTimeStamp&quot;);
        }
    }    [IgnoreDataMember]
    public string ExchangedTimeStamp
    {
        get
        {
            if (_result == null)
                return string.Empty;            return string.Format(&quot;Data freshness:\n{0} at {1}&quot;,
                _result.Timestamp.ToShortDateString(),
                _result.Timestamp.ToShortTimeString());
        }
    }    [DataMember]
    public CurrencyCachedExchangeRate[] CurrenciesCachedExchangeRates
    {
        get
        {
            return Currencies
                .Select(x =&gt; new CurrencyCachedExchangeRate()
                {
                    CurrencyIndex = Array.IndexOf(Currencies, x),
                    CachedExchangeRate = x.CachedExchangeRate,
                    CachedExchangeRateUpdatedOn = x.CachedExchangeRateUpdatedOn
                })
                .ToArray();
        }
        set
        {
            foreach (var currencyData in value)
            {
                if (currencyData.CurrencyIndex &gt;= Currencies.Length)
                    continue;                var currency = Currencies[currencyData.CurrencyIndex];                currency.CachedExchangeRate = currencyData.CachedExchangeRate;
                currency.CachedExchangeRateUpdatedOn = currencyData.CachedExchangeRateUpdatedOn;
            }
        }
    }    #endregion    //Full previous code    public void ExchangeCurrency()
    {
        if (Busy)
            return;        BusyMessage = &quot;Exchanging amount...&quot;;        _currencyExchangeService.ExchangeCurrency(_amount, _fromCurrency, _toCurrency, true, CurrencyExchanged, null);
    }    public void UpdateCachedExchangeRates()
    {
        if (Busy)
            return;        BusyMessage = &quot;Updating cached exchange rates...&quot;;        _currencyExchangeService.UpdateCachedExchangeRates(ExchangeRatesUpdated, null);
    }    private void CurrencyExchanged(ICurrencyExchangeResult result)
    {
        InvokeOnUiThread(() =&gt;
        {
            Result = result;            BusyMessage = null;            if (result.Error != null)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                    System.Diagnostics.Debugger.Break();
                else
                    MessageBox.Show(&quot;An error has ocorred!&quot;, &quot;Error&quot;, MessageBoxButton.OK);
            }
        });
    }    private void ExchangeRatesUpdated(ICachedExchangeRatesUpdateResult result)
    {
        InvokeOnUiThread(() =&gt;
        {
            BusyMessage = null;            Save();            if (result.Error != null)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                    System.Diagnostics.Debugger.Break();
                else
                    MessageBox.Show(&quot;An error has ocorred!&quot;, &quot;Error&quot;, MessageBoxButton.OK);
            }
        });
    }    private void InvokeOnUiThread(Action action)
    {
        var dispatcher = System.Windows.Deployment.Current.Dispatcher;        if (dispatcher.CheckAccess())
            action();
        else
            dispatcher.BeginInvoke(action);
    }    #region Auxiliary Classes    public class CurrencyCachedExchangeRate
    {
        [DataMember]
        public int CurrencyIndex { get; set; }        [DataMember]
        public double CachedExchangeRate { get; set; }        [DataMember]
        public DateTime CachedExchangeRateUpdatedOn { get; set; }
    }    #endregion
}</pre></p><p>The first thing you will notice here is a new ExchangedTimeStamp read-only property that feeds the interface with the date string to denote when the used currency data was obtained. The interface is notified that this property value has changed when the Result property value is also changed.</p><p>Further down there’s another new property, CurrenciesCachedExchangeRates, that stores the cached exchange rates. For this to work, we have an auxiliary class called CurrencyCachedExchangeRate that stores the currency index along with the exchange rate as well as the update timestamp.</p><p>The UpdateCachedExchangeRates method allows users to manually force an update over the cached exchange rates.</p><p>The CurrencyExchanged and ExchangeRatesUpdated callbacks use the InvokeOnUiThread method to make sure that their codes run properly on the UI thread.</p><h4>The View</h4><p>Two simple changes have been made in the MainPage.xaml (our main View): an area on the screen has been added to show the exchange operation result timestamp, and a menu option has been added to force a full exchange rate update.</p><p>To make the first change, add a simple TextArea on the bottom StackPanel and bind it to the ExchangedTimeStamp property of the ViewModel:</p><p><strong>XAML<br></strong><pre class="brush: text">&lt;StackPanel x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;
    &lt;TextBlock Margin=&quot;12,0,0,-5&quot; Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot;&gt;Amount&lt;/TextBlock&gt;
    &lt;TextBox InputScope=&quot;TelephoneNumber&quot; Text=&quot;{Binding Amount, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}&quot; /&gt;
    &lt;TextBlock Margin=&quot;12,10,0,-5&quot; Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot;&gt;From&lt;/TextBlock&gt;
    &lt;toolkit:ListPicker ItemsSource=&quot;{Binding Currencies}&quot; SelectedItem=&quot;{Binding FromCurrency, Mode=TwoWay}&quot; FullModeHeader=&quot;FROM CURRENCY&quot; Style=&quot;{StaticResource CurrencyListPicker}&quot; /&gt;
    &lt;TextBlock Margin=&quot;12,10,0,-5&quot; Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot;&gt;To&lt;/TextBlock&gt;
    &lt;toolkit:ListPicker ItemsSource=&quot;{Binding Currencies}&quot; SelectedItem=&quot;{Binding ToCurrency, Mode=TwoWay}&quot; FullModeHeader=&quot;TO CURRENCY&quot; Style=&quot;{StaticResource CurrencyListPicker}&quot; /&gt;
    &lt;StackPanel&gt;
        &lt;TextBlock Style=&quot;{StaticResource PhoneTextGroupHeaderStyle}&quot; Text=&quot;{Binding ExchangedCurrency}&quot;&gt;&lt;/TextBlock&gt;
        &lt;TextBlock Margin=&quot;25, 0, 0, 0&quot; Style=&quot;{StaticResource PhoneTextTitle1Style}&quot; Text=&quot;{Binding ExchangedAmount}&quot;&gt;&lt;/TextBlock&gt;
        &lt;TextBlock Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot; Text=&quot;{Binding ExchangedTimeStamp}&quot; TextWrapping=&quot;Wrap&quot; TextAlignment=&quot;Right&quot;&gt;&lt;/TextBlock&gt;
    &lt;/StackPanel&gt;
&lt;/StackPanel&gt;</pre></p><p>As for the “update exchange rates” menu option, add a new ApplicationBarMenuItem to the MenuItems collection, set the appropriate text, and add a handler for the click event:</p><p><strong>XAML<br></strong><pre class="brush: text">&lt;phone:PhoneApplicationPage.ApplicationBar&gt;
    &lt;shell:ApplicationBar IsVisible=&quot;True&quot; IsMenuEnabled=&quot;True&quot;&gt;
        &lt;shell:ApplicationBarIconButton IconUri=&quot;/Images/appbar.money.usd.png&quot; Text=&quot;Exchange&quot; Click=&quot;ExchangeIconButton_Click&quot; /&gt;
        &lt;shell:ApplicationBar.MenuItems&gt;
            &lt;shell:ApplicationBarMenuItem Text=&quot;update exchange rates&quot; Click=&quot;UpdateExchangeRatesMenuItem_Click&quot; /&gt;
            &lt;shell:ApplicationBarMenuItem Text=&quot;about&quot; Click=&quot;AboutMenuItem_Click&quot; /&gt;
        &lt;/shell:ApplicationBar.MenuItems&gt;
    &lt;/shell:ApplicationBar&gt;
&lt;/phone:PhoneApplicationPage.ApplicationBar&gt;</pre></p><p>Now, all that is missing is implementing the UpdateExchangeRatesMenuItem_To do so, click the event handler in the MainPage.xaml.cs:</p><p><strong>C#<br></strong><pre class="brush: csharp">private void UpdateExchangeRatesMenuItem_Click(object sender, EventArgs e)
{
    var viewModel = DataContext as MainViewModel;    if (viewModel == null)
        return;    Dispatcher.BeginInvoke(() =&gt;
    {
        viewModel.UpdateCachedExchangeRates();
    });
}</pre></p><h3>Conclusion</h3><p>The bottom line is that your application is as good as the data source you use. By utilizing a new (better) data source, some really simple changes to the code, we now have the Currency Converter—faster than ever!</p><p>And just in time: the coffee is ready!</p><h3>About The Author</h3><p>Pedro Lamas is a Portuguese .Net Senior Developer on Microsoft’s Partner DevScope, where he works with all the cool stuff that Microsoft .Net has to offer its developers!</p><p>He’s also one of the administrators of PocketPT.net, the largest Windows Phone Portuguese community, where his contribution is mostly visible on support for Windows Phone developers, and as a speaker for Windows Phone Development in Microsoft Portugal Events.</p><p>You can read his <a href="http://www.pedrolamas.com">blog</a> or contact him via <a href="http://twitter.com/pedrolamas">twitter</a>!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f1949595c4fb4be1924f9ed4011b1714">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-v2--Now-on-Caffeine</comments>
      <itunes:summary> Taking user feedback about the application into consideration, it’s time to make some improvements! JHere are some of the reports we got from the users:The application is too slow when exchanging currencies It uses too much data traffic/should cache the exchange rates It doesn’t work for some currencies The results are inaccurate/using out-of-date exchange rates So, what we can see from these comments is that we need a better data source, and that we should use some sort of caching mechanism…I think I’ll go ahead and put some coffee on to boil!To Bing or not to Bing…The first version of Currency Converter used Bing to make the exchanges, which resulted in some of the reports you read above!For this version, however, we decided to use MSN Money because it has more accurate and up-to-date data, and because it works every time no matter the currency!MSN Money provides a very nice page on which we can see current currency exchange rates in relation to US Dollars; just open your Internet Explorer 8.0&amp;#43; and navigate to the following URL:http://moneycentral.msn.com/investor/market/exchangerates.aspxAs you can see here, we have all the data we need to convert from X to USD and from USD to X, and we can even convert from X to USD to Y.So, why not just get all of this data on a single request, cache it, and use it offline to make the currency exchanges? JLike before, we will retrieve the data we require from the page HTML by using Regular Expressions. To do so, open Internet Explorer Developer Tools (press F12), use the “Select element by click” option (Ctrl &amp;#43; B), and click on the “Argentine Peso” text; you’ll get something looking like this:Using the information above, we can see a pattern in the code:HTML&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;CURRENCY&amp;lt;/td&amp;gt;
    &amp;lt;td style=”text-align:right”&amp;gt;&amp;lt;a SOMETHING&amp;gt;VALUE_IN_USD&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td style=”text-align:right”&amp;gt;&amp;lt;a SOMETHING&amp;gt;VALUE_PER_USD&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;Now that we know the </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-v2--Now-on-Caffeine</link>
      <pubDate>Mon, 02 May 2011 12:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Currency-Converter-v2--Now-on-Caffeine</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/d2ef20a2-9867-4013-9399-5c9a685add18.png" height="75" width="100"/>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/79fa25a3-94ee-45da-a789-4929539801c5.png" height="165" width="220"/>      
      <dc:creator>Pedro Lamas</dc:creator>
      <itunes:author>Pedro Lamas</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-v2--Now-on-Caffeine/RSS</wfw:commentRss>
      <category>MVVM</category>
      <category>Silveright</category>
      <category>Silverlight</category>
      <category>Web Services</category>
      <category>Windows Phone</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Simple Dependency Injection with XAML</title>
      <description><![CDATA[ <p>Have you ever wanted the flexibility of dependency injection without having to implement a full-blown IoC solution?&nbsp; Maybe you just want an easy way to pass concrete services to your ViewModel?&nbsp; This short video will show you you can use XAML to configure your ViewModels to provide a property-based dependency injection solution.&nbsp; You can also read a <a href="http://slickthought.net/post.aspx?id=3c779bba-d72f-4024-99a3-17acbcb647f7">full write up and download demo code&nbsp;on my blog</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:8113fd523f384587a0319e6e017aee5b">]]></description>
      <comments>http://channel9.msdn.com/Blogs/SlickThought/Simple-Dependency-Injection-with-XAML</comments>
      <itunes:summary> Have you ever wanted the flexibility of dependency injection without having to implement a full-blown IoC solution?&amp;nbsp; Maybe you just want an easy way to pass concrete services to your ViewModel?&amp;nbsp; This short video will show you you can use XAML to configure your ViewModels to provide a property-based dependency injection solution.&amp;nbsp; You can also read a full write up and download demo code&amp;nbsp;on my blog.</itunes:summary>
      <itunes:duration>670</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/SlickThought/Simple-Dependency-Injection-with-XAML</link>
      <pubDate>Tue, 18 Jan 2011 21:25:39 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/SlickThought/Simple-Dependency-Injection-with-XAML</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_100_ch9.jpg" height="75" width="100"/>
      <media:thumbnail url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_220_ch9.jpg" height="165" width="220"/>
      <media:thumbnail url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_512_ch9.jpg" height="384" width="512"/>
      <media:thumbnail url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_custom_ch9.jpg" height="384" width="512"/>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_2MB_ch9.wmv" expression="full" duration="670" fileSize="103625471" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_ch9.mp3" expression="full" duration="670" fileSize="5364208" type="audio/mp3" medium="audio"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_ch9.wma" expression="full" duration="670" fileSize="5427199" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_ch9.wmv" expression="full" duration="670" fileSize="32729453" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_high_ch9.mp4" expression="full" duration="670" fileSize="182831654" type="video/mp4" medium="video"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_low_ch9.mp4" expression="full" duration="670" fileSize="18725103" type="video/mp4" medium="video"/>
        <media:content url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_Zune_ch9.wmv" expression="full" duration="670" fileSize="29241508" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://smooth.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI.ism/manifest" expression="full" duration="670" fileSize="8426" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/ee5b/8113fd52-3f38-4587-a031-9e6e017aee5b/SimpleXamlDI_ch9.wmv" length="32729453" type="video/x-ms-wmv"/>
      <dc:creator>Jeff Brand</dc:creator>
      <itunes:author>Jeff Brand</itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/SlickThought/Simple-Dependency-Injection-with-XAML/RSS</wfw:commentRss>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Currency Converter for Windows Phone 7</title>
      <description><![CDATA[ <p>The purpose of this article is to show how you can make your very own, very simple Currency Converter application for Windows Phone 7, using Bing to make all the hard exchanging work!</p><h2><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/conversion_splash.png"><img title="conversion_splash" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/conversion_splash_thumb.png" alt="conversion_splash" width="288" height="480" border="0"></a>Introduction</h2><p>Microsoft has done an absolutely amazing job with the Windows Phone 7, giving each and every one of us all of the necessary tools to make our applications blend nicely on it; and the best part—the tools are, and will always be, free!!! J</p><h2>Using Bing for the currency exchange</h2><p>First let's look at what happens when I open up Bing on my browser, and enter a search query like “1 US Dollar in Euros”:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb.png" alt="image" width="500" height="375" border="0"></a></p><p>As you can see, Bing correctly understood my query, and knew that I was looking for an exchange rate. Then MSN Money made the exchange and presented the result.</p><p>Also, notice that the address displays as:</p><p>http://www.bing.com/search?q=<strong>1&#43;US&#43;Dollar&#43;in&#43;Euros</strong>&amp;go=&amp;form=QBRE&amp;qs=n&amp;sk=&amp;sc=1-20</p><p>OK, but how can we use this to feed the WP7 application? Call the Internet Explorer Developer Tools (just press F12 on your IE8&#43;) and use the “Select element by click” option (Ctrl &#43; B) to select the result on the page and see its HTML code. The result will look just like this:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_3.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_3.png" alt="image" width="500" height="406" border="0"></a></p><p>Now we know how to build the Bing currency exchange search query (using “http://www.bing.com/search?q=<strong>{VALUE}</strong>&#43;<strong>{SOURCE_CURRENCY}</strong>&#43;in&#43;<strong>{DESTINATION_CURRENCY}</strong>&amp;go=&amp;form=QBRE&amp;qs=n&amp;sk=&amp;sc=1-20”) and also how to find the results on the returned HTML (search the “&lt;span class=&quot;sc_bigLine&quot;&gt;<strong>RESULT</strong>&lt;/span&gt;”).</p><p>The final task is selecting that span tag on the full HTML and then extracting the converted amount; for this task, I'll be using the following Regular Expression (using System.Text.RegularExpressions):</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">static</span> Regex _resultRegex =   <span class="kwrd">new</span> Regex(<span class="str">&quot;&lt;span class=\&quot;sc_bigLine\&quot;&gt;.*? = (?&lt;value&gt;[0-9.,]&#43;).*?&lt;/span&gt;&quot;</span>);</pre><p>&nbsp;</p><p>This expression searches the HTML code for a span with class “sc_bigLine” and inner content matching something like the above example: “1 USD = 0.71270 EUR”.</p><p>The expression also allows me to extract the number after the “=” sign by using Groups[“value&quot;].value property.</p><h2>MVVM is our friend!</h2><p>I'll start by quoting the Wikipedia:</p><p><em>The Model View ViewModel (MVVM) is an architectural pattern used in software engineering (…) is targeted at modern UI development platforms (Windows Presentation Foundation and Silverlight) in which there is a User Experience (UX) developer who has different requirements than a more “traditional” developer (i.e. oriented toward business logic and back end development).</em></p><p>Basically, the point is to clearly separate the user interface from all the business logic and data that our application will use!</p><p>We can summarize the MVVM pattern with this schema:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_4.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_4.png" alt="image" width="295" height="290" border="0"></a></p><p>The View is the basic XAML for the user interface (although sometimes it can have a C# file attached to it) that will use Data Binding to read and change properties on the ViewModel, and Actions to invoke the methods.</p><p>The ViewModel is the abstraction of the View and will do all the work for binding the View to the Model, with the necessary data conversion.</p><p>The Model can represent the actual object model instance in a known state, or just a data access layer.</p><p>There is one basic rule in MVVM: don't look up! The Model has no knowledge of either the ViewModel or the View, and the ViewModel has no knowledge of the View.</p><p>This brings a new challenge on how to make the three components talk between themselves, and that's where notifications come along!</p><p>We use notifications to communicate changes from a lower component to an upper one; when the upper component gets notified, it will then query the lower for what changed and act accordingly to the new state!</p><p>You can read more about MVVM throughout the internet, but there is an article by Shawn Wildermuth that's one of the best I've seen; you can read it here: <a href="http://msdn.microsoft.com/en-us/magazine/dd458800.aspx">http://msdn.microsoft.com/enus/magazine/dd458800.aspx</a>.</p><h2>The Model</h2><p>We will start at the very bottom (a.k.a. the Model), and as such I've created the following Interfaces to support our Data Model:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_5.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_5.png" alt="image" width="401" height="150" border="0"></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_6.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_6.png" alt="image" width="147" height="115" border="0"></a></p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">using</span> System; <span class="kwrd">public</span> <span class="kwrd">interface</span> ICurrencyExchangeService{    ICurrency[] Currencies { get; }    <span class="kwrd">void</span> ExchangeCurrency(        <span class="kwrd">double</span> amount,         ICurrency fromCurrency,         ICurrency toCurrency,         Action&lt;ICurrencyExchangeResult&gt; callback);} <span class="kwrd">public</span> <span class="kwrd">interface</span> ICurrency{    <span class="kwrd">string</span> Name { get; }} <span class="kwrd">public</span> <span class="kwrd">interface</span> ICurrencyExchangeResult{    Exception Error { get; }    <span class="kwrd">string</span> ExchangedCurrency { get; }    <span class="kwrd">double</span> ExchangedAmount { get; }}</pre><p>&nbsp;</p><p>From these three interfaces, we will extend our Bing Currency Exchange provider:</p><p>The abstract CurrencyExchangeServiceBase class implements the ICurrencyExchangeService.ExchangeCurrency method to do all the asynchronous work required to request data from a webserver and retrieve the resulting HTML; to achieve its goal, the CurrencyExchangeServiceBase has two abstract methods that must be implemented: CreateRequestUrl, to get the request url that will be passed to the WebRequest, and GetResultFromResponseContent, to parse the received HTML and return the exchanged value.</p><p>We then extend the BingCurrencyExchangeService from CurrencyExchangeServiceBase, implementing the CreateRequestUrl and GetResultFromResponseContent required methods and the ICurrencyExchangeService.Currencies property including all currencies supported by this service instance.</p><p>We have also a basic ICurrency interface implementation class called BingCurrency.</p><p>This is the CurrencyExchangeServiceBase abstract class implementation:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_7.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_7.png" alt="image" width="454" height="412" border="0"></a></p><p><strong>C#</strong></p><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> CurrencyExchangeServiceBase : ICurrencyExchangeService{   <span class="kwrd">public</span> <span class="kwrd">abstract</span> ICurrency[] Currencies { get; }   <span class="kwrd">protected</span> <span class="kwrd">abstract</span> <span class="kwrd">string</span> CreateRequestUrl(        <span class="kwrd">double</span> amount,         ICurrency fromCurrency,         ICurrency toCurrency);   <span class="kwrd">protected</span> <span class="kwrd">abstract</span> <span class="kwrd">double</span>         GetResultFromResponseContent(<span class="kwrd">string</span> responseContent);   <span class="kwrd">public</span> <span class="kwrd">void</span> ExchangeCurrency(        <span class="kwrd">double</span> amount,         ICurrency fromCurrency,         ICurrency toCurrency,         Action&lt;ICurrencyExchangeResult&gt; callback)   {      var url = CreateRequestUrl(amount, fromCurrency, toCurrency);      var request = HttpWebRequest.Create(url);      request.BeginGetResponse(ar =&gt;       {         <span class="kwrd">try</span>         {            var response = (HttpWebResponse)request.EndGetResponse(ar);            <span class="kwrd">if</span> (response.StatusCode == HttpStatusCode.OK)            {               <span class="kwrd">string</span> responseContent;               <span class="kwrd">using</span> (var streamReader =                   <span class="kwrd">new</span> StreamReader(response.GetResponseStream()))               {                  responseContent = streamReader.ReadToEnd();               }               var exchangedCurrency =                   GetResultFromResponseContent(responseContent);               callback(                  <span class="kwrd">new</span> CurrencyExchangeResult(                     toCurrency.Name,                      exchangedCurrency));            }            <span class="kwrd">else</span>            {               <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(                <span class="kwrd">string</span>.Format(<span class="str">&quot;Http Error: ({0}) {1}&quot;</span>,                  response.StatusCode,                  response.StatusDescription));            }         }         <span class="kwrd">catch</span> (Exception ex)         {            callback(<span class="kwrd">new</span> CurrencyExchangeResult(ex));         }      }, <span class="kwrd">null</span>);   }}</pre><p>&nbsp;</p><p>As I said before, this is an abstract class that requires any inheritor to implement the Currencies property as well as the CreateRequestUrl and GetResultFromResponseContent functions—and that's exactly what the BingCurrencyExchangeService class does:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> BingCurrencyExchangeService : CurrencyExchangeServiceBase{   <span class="kwrd">private</span> <span class="kwrd">static</span> Regex _resultRegex =       <span class="kwrd">new</span> Regex(<span class="str">&quot;&lt;span class=\&quot;sc_bigLine\&quot;&gt;.*? = (?&lt;value&gt;[0-9.,]&#43;).*?&lt;/span&gt;&quot;</span>);   <span class="kwrd">private</span> <span class="kwrd">static</span> ICurrency[] _currencies = <span class="kwrd">new</span> ICurrency[] {       <span class="kwrd">new</span> BingCurrency(<span class="str">&quot;Euro&quot;</span>),      <span class="kwrd">new</span> BingCurrency(<span class="str">&quot;US Dollar&quot;</span>)      <span class="rem">//all available currencies will go here!</span>   };   <span class="preproc">#endregion</span>   <span class="kwrd">public</span> <span class="kwrd">override</span> ICurrency[] Currencies   {      get      {         <span class="kwrd">return</span> _currencies;      }   }   <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">string</span> CreateRequestUrl(<span class="kwrd">double</span> amount, ICurrency fromCurrency, ICurrency toCurrency)   {      <span class="kwrd">return</span> <span class="kwrd">string</span>.Format(         <span class="str">@&quot;http://www.bing.com/search?q={0}&#43;{1}&#43;in&#43;{2}&amp;scope=web&amp;mkt=en-US&amp;FORM=W0LH&quot;</span>,         amount,         fromCurrency.Name.Replace(<span class="str">&quot; &quot;</span>, <span class="str">&quot;&#43;&quot;</span>),         toCurrency.Name.Replace(<span class="str">&quot; &quot;</span>, <span class="str">&quot;&#43;&quot;</span>));   }   <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">double</span> GetResultFromResponseContent(<span class="kwrd">string</span> responseContent)   {      var match = _resultRegex.Match(responseContent);      <span class="kwrd">if</span> (match.Success)         <span class="kwrd">return</span> <span class="kwrd">double</span>.Parse(            match.Groups[<span class="str">&quot;value&quot;</span>].Value,             CultureInfo.InvariantCulture);      <span class="kwrd">else</span>         <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;Conversion not returned!&quot;</span>);   }}</pre><p>&nbsp;</p><p>As you can see here, the BingCurrencyExchangeService class knows how to build the Bing search url if given the currencies and the value of exchange, and also how to get the converted value out of the response HTML code (notice the usage of our regular expression).</p><h2>The ViewModel</h2><p>The ViewModel has a basic inheritance requirement: using INotifyPropertyChanged to notify the user interface of property value changes.</p><p>Our MainViewModel class will have to expose three base data properties for the user interface controls: FromCurrency, ToCurrency, and Amount.</p><p>All assembled, this is how the ViewModel looks:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> MainViewModel : INotifyPropertyChanged{   <span class="kwrd">private</span> ICurrencyExchangeService _currencyExchangeService;   <span class="kwrd">private</span> <span class="kwrd">double</span> _amount;   <span class="kwrd">private</span> ICurrency _fromCurrency;   <span class="kwrd">private</span> ICurrency _toCurrency;   <span class="kwrd">public</span> ICurrencyExchangeService CurrencyExchangeService   {      get      {         <span class="kwrd">return</span> _currencyExchangeService;      }      set      {         <span class="kwrd">if</span> (_currencyExchangeService == <span class="kwrd">value</span>)            <span class="kwrd">return</span>;         _currencyExchangeService = <span class="kwrd">value</span>;         _fromCurrency = Currencies.FirstOrDefault(x =&gt; x.Name == <span class="str">&quot;US Dollar&quot;</span>) ?? Currencies[0];         _toCurrency = Currencies.FirstOrDefault(x =&gt; x.Name == <span class="str">&quot;Euro&quot;</span>) ?? Currencies[1];         RaisePropertyChanged(<span class="str">&quot;CurrencyExchangeService&quot;</span>);         RaisePropertyChanged(<span class="str">&quot;Currencies&quot;</span>);      }   }   <span class="kwrd">public</span> ICurrency[] Currencies   {      get      {         <span class="kwrd">return</span> _currencyExchangeService.Currencies;      }   }   <span class="kwrd">public</span> <span class="kwrd">string</span> Amount   {      get      {         <span class="kwrd">return</span> _amount.ToString(<span class="str">&quot;0.00&quot;</span>);      }      set      {         <span class="kwrd">double</span> amount;         <span class="kwrd">if</span> (<span class="kwrd">double</span>.TryParse(<span class="kwrd">value</span>, <span class="kwrd">out</span> amount))         {            <span class="kwrd">if</span> (_amount == amount)               <span class="kwrd">return</span>;            _amount = amount;            RaisePropertyChanged(<span class="str">&quot;Amount&quot;</span>);         }         <span class="kwrd">else</span>            <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;Please enter a valid Amount&quot;</span>);      }   }   <span class="kwrd">public</span> ICurrency FromCurrency   {      get      {         <span class="kwrd">return</span> _fromCurrency;      }      set      {         <span class="kwrd">if</span> (_fromCurrency == <span class="kwrd">value</span>)            <span class="kwrd">return</span>;         _fromCurrency = <span class="kwrd">value</span>;         RaisePropertyChanged(<span class="str">&quot;FromCurrency&quot;</span>);      }   }   <span class="kwrd">public</span> ICurrency ToCurrency   {      get      {         <span class="kwrd">return</span> _toCurrency;      }      set      {         <span class="kwrd">if</span> (_toCurrency == <span class="kwrd">value</span>)            <span class="kwrd">return</span>;         _toCurrency = <span class="kwrd">value</span>;         RaisePropertyChanged(<span class="str">&quot;ToCurrency&quot;</span>);      }   }   <span class="kwrd">public</span> MainViewModel()   {      CurrencyExchangeService = <span class="kwrd">new</span> BingCurrencyExchangeService();      Amount = <span class="str">&quot;100&quot;</span>;   }   <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;   <span class="kwrd">private</span> <span class="kwrd">void</span> RaisePropertyChanged(<span class="kwrd">string</span> propertyName)   {      <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)         PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(propertyName));   }}</pre><p>&nbsp;</p><p>In order to allow the user to change the FromCurrency and ToCurrency properties, we need to list the available ones; as such, we added a Currencies property to return the ICurrency[] Currencies property of the Model instance.</p><p>On the MainViewModel constructor, set the CurrencyExchangeService property to a new BingCurrencyExchangeService instance, making it retrieve “Euro” and “US Dollar” (if available; if not, get the 1<sup>st</sup> and 2<sup>nd</sup> one instead) as the two default exchange currencies, and then set the Amount property to an initial value of “100.”</p><p>The PropertyChanged event is a basic implementation of the INotifyPropertyChanged interface, with a helper method called RaisePropertyChanged used to invoke the event.</p><p>Now we need to add functionality to request a currency exchange operation and show the results on the user interface:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> MainViewModel : INotifyPropertyChanged{    <span class="rem">//remaining code...</span>    <span class="kwrd">private</span> ICurrencyExchangeResult _result;    <span class="kwrd">public</span> ICurrencyExchangeResult Result    {        get        {            <span class="kwrd">return</span> _result;        }        <span class="kwrd">protected</span> set        {            <span class="kwrd">if</span> (_result == <span class="kwrd">value</span>)                <span class="kwrd">return</span>;            _result = <span class="kwrd">value</span>;            RaisePropertyChanged(<span class="str">&quot;Result&quot;</span>);            RaisePropertyChanged(<span class="str">&quot;ExchangedCurrency&quot;</span>);            RaisePropertyChanged(<span class="str">&quot;ExchangedAmount&quot;</span>);        }    }    <span class="kwrd">public</span> <span class="kwrd">string</span> ExchangedCurrency    {        get        {            <span class="kwrd">if</span> (_result == <span class="kwrd">null</span>)                <span class="kwrd">return</span> <span class="kwrd">string</span>.Empty;            <span class="kwrd">return</span> _result.ExchangedCurrency;        }    }    <span class="kwrd">public</span> <span class="kwrd">string</span> ExchangedAmount    {        get        {            <span class="kwrd">if</span> (_result == <span class="kwrd">null</span>)                <span class="kwrd">return</span> <span class="kwrd">string</span>.Empty;            <span class="kwrd">return</span> _result.ExchangedAmount.ToString(<span class="str">&quot;N2&quot;</span>);        }    }    <span class="kwrd">public</span> <span class="kwrd">void</span> ExchangeCurrency()    {        _currencyExchangeService.ExchangeCurrency(_amount, _fromCurrency, _toCurrency, CurrencyExchanged);    }    <span class="kwrd">private</span> <span class="kwrd">void</span> CurrencyExchanged(ICurrencyExchangeResult result)    {        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =&gt;        {            Result = result;        });    }}</pre><p>&nbsp;</p><p>The ExchangeCurrency method will be used to request a currency exchange operation on the Model instance, including the entered data. When the operation ends, the CurrencyExchanged method will be invoked and we will then get an ICurrencyExchangeResult instance with the results; this method will be asynchronously called on another thread, so we will need get the current Dispatcher and use it to invoke the changes to the MainViewModel.Result property (so that they are made on the interface thread).</p><p>As the Result property gets changed, it will also make property changed notifications to the ExchangedCurrency and ExchangedAmount properties, allowing the user interface to show the returned values.</p><h2>The View</h2><p>The View that will support our application is really quite simple!</p><p>The basic requirements are two ListPicker controls (these are implemented on the Silverlight Toolkit): one for each Currency (the MainViewModel FromCurrency and ToCurrency properties) and a TextBox for the Amount.</p><p>We also need two more TextAreas to show the currency exchange results (one for the ExchangedCurrency property and the other for the ExchangedAmount property, both from our MainViewModel).</p><p>Using the current MainPage.xaml, start by adding a reference to the Silverlight for Windows Phone Toolkit, like so:</p><p><strong>XAML <br></strong></p><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">phone:PhoneApplicationPage</span><span class="attr">xmlns:toolkit</span><span class="kwrd">=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit&quot;</span>&amp;<span class="attr">lt</span>;!<span class="attr">--remaining</span> <span class="attr">code</span>... <span class="attr">--</span><span class="kwrd">&gt;</span></pre><p>&nbsp;</p><p>Then, I'll change the default ContentPanel control from a Grid to a StackPanel, and add the required controls to edit the Currencies and the entry Value:</p><p><strong>XAML <br></strong></p><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ContentPanel&quot;</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">=&quot;1&quot;</span> <span class="attr">Margin</span><span class="kwrd">=&quot;12,0&quot;</span><span class="kwrd">&gt;</span>   <span class="kwrd">&lt;</span><span class="html">TextBlock</span>       <span class="attr">Margin</span><span class="kwrd">=&quot;12,0,0,-5&quot;</span>       <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource PhoneTextSubtleStyle}&quot;</span><span class="kwrd">&gt;</span>      Amount   <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span>   <span class="kwrd">&lt;</span><span class="html">TextBox</span>       <span class="attr">InputScope</span><span class="kwrd">=&quot;TelephoneNumber&quot;</span>       <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Amount, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}&quot;</span> <span class="kwrd">/&gt;</span>   <span class="kwrd">&lt;</span><span class="html">TextBlock</span>       <span class="attr">Margin</span><span class="kwrd">=&quot;12,10,0,-5&quot;</span>       <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource PhoneTextSubtleStyle}&quot;</span><span class="kwrd">&gt;</span>         From   <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span>   <span class="kwrd">&lt;</span><span class="html">toolkit:ListPicker</span>       <span class="attr">ItemsSource</span><span class="kwrd">=&quot;{Binding Currencies}&quot;</span>       <span class="attr">SelectedItem</span><span class="kwrd">=&quot;{Binding FromCurrency, Mode=TwoWay}&quot;</span>       <span class="attr">FullModeHeader</span><span class="kwrd">=&quot;FROM CURRENCY&quot;</span>       <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource CurrencyListPicker}&quot;</span> <span class="kwrd">/&gt;</span>   <span class="kwrd">&lt;</span><span class="html">TextBlock</span>       <span class="attr">Margin</span><span class="kwrd">=&quot;12,10,0,-5&quot;</span>       <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource PhoneTextSubtleStyle}&quot;</span><span class="kwrd">&gt;</span>      To   <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span>   <span class="kwrd">&lt;</span><span class="html">toolkit:ListPicker</span>       <span class="attr">ItemsSource</span><span class="kwrd">=&quot;{Binding Currencies}&quot;</span>       <span class="attr">SelectedItem</span><span class="kwrd">=&quot;{Binding ToCurrency, Mode=TwoWay}&quot;</span>       <span class="attr">FullModeHeader</span><span class="kwrd">=&quot;TO CURRENCY&quot;</span>       <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource CurrencyListPicker}&quot;</span> <span class="kwrd">/&gt;</span>   <span class="kwrd">&lt;</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span>      <span class="kwrd">&lt;</span><span class="html">TextBlock</span>          <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource PhoneTextGroupHeaderStyle}&quot;</span>          <span class="attr">Text</span><span class="kwrd">=&quot;{Binding ExchangedCurrency}&quot;</span> <span class="kwrd">/&gt;</span>      <span class="kwrd">&lt;</span><span class="html">TextBlock</span>          <span class="attr">Margin</span><span class="kwrd">=&quot;25, 0, 0, 0&quot;</span>          <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource PhoneTextTitle1Style}&quot;</span>          <span class="attr">Text</span><span class="kwrd">=&quot;{Binding ExchangedAmount}&quot;</span> <span class="kwrd">/&gt;</span>   <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span></pre><p>&nbsp;</p><p>Here's how it looks right now:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_8.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10098706/image_thumb_8.png" alt="image" width="287" height="292" border="0"></a></p><p>Notice the CurrencyListPicker style applied to the two ListPicker controls on the code above? Here it is:</p><p><strong>XAML <br></strong></p><pre class="csharpcode">&lt;phone:PhoneApplicationPage.Resources&gt;   &lt;Style x:Key=<span class="str">&quot;CurrencyListPicker&quot;</span> TargetType=<span class="str">&quot;toolkit:ListPicker&quot;</span>&gt;      &lt;Setter          Property=<span class="str">&quot;DisplayMemberPath&quot;</span>          Value=<span class="str">&quot;Name&quot;</span> /&gt;      &lt;Setter          Property=<span class="str">&quot;CacheMode&quot;</span>          Value=<span class="str">&quot;BitmapCache&quot;</span> /&gt;      &lt;Setter Property=<span class="str">&quot;FullModeItemTemplate&quot;</span>&gt;         &lt;Setter.Value&gt;            &lt;DataTemplate&gt;               &lt;StackPanel                      Orientation=<span class="str">&quot;Horizontal&quot;</span>                      Margin=<span class="str">&quot;16 21 0 20&quot;</span>&gt;                  &lt;TextBlock                      Text=<span class="str">&quot;{Binding Name}&quot;</span>                      FontSize=<span class="str">&quot;43&quot;</span>                      FontFamily=<span class="str">&quot;{StaticResource PhoneFontFamilyLight}&quot;</span>/&gt;               &lt;/StackPanel&gt;            &lt;/DataTemplate&gt;         &lt;/Setter.Value&gt;      &lt;/Setter&gt;   &lt;/Style&gt;&lt;/phone:PhoneApplicationPage.Resources&gt;</pre><p>&nbsp;</p><p>This style sets the initial values of three properties on the ListPickers: the DisplayMemberPath (it will be binded to the ICurrency.Name property), the CacheMode (for optimization only), and, most importantly, the FullModeItemTemplate, which indicates how to show each item when the ListPicker window pops up.</p><p>The next step will be adding the “Exchange” button to the bottom ApplicationBar, like so:</p><p><strong>XAML <br></strong></p><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">phone:PhoneApplicationPage.ApplicationBar</span><span class="kwrd">&gt;</span>   <span class="kwrd">&lt;</span><span class="html">shell:ApplicationBar</span>       <span class="attr">IsVisible</span><span class="kwrd">=&quot;True&quot;</span>       <span class="attr">IsMenuEnabled</span><span class="kwrd">=&quot;False&quot;</span><span class="kwrd">&gt;</span>      <span class="kwrd">&lt;</span><span class="html">shell:ApplicationBarIconButton</span>          <span class="attr">IconUri</span><span class="kwrd">=&quot;/Images/appbar.money.usd.png&quot;</span>          <span class="attr">Text</span><span class="kwrd">=&quot;Exchange&quot;</span>          <span class="attr">Click</span><span class="kwrd">=&quot;ExchangeIconButton_Click&quot;</span> <span class="kwrd">/&gt;</span>   <span class="kwrd">&lt;/</span><span class="html">shell:ApplicationBar</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">phone:PhoneApplicationPage.ApplicationBar</span><span class="kwrd">&gt;</span> </pre><p>&nbsp;</p><p>Remember to create an Images folder in your project and copy the required “appbar.money.usd.png” image to it (you can find this and other ApplicationBar icons in your “%ProgramFiles%\Microsoft SDKs\Windows Phone\v7.0\Icons\dark”); then, set its “Build” and “Copy to Output Directory” properties to “Content” and “Copy always”, respectively.</p><p>On the MainPage.xaml.cs, we'll add the ExchangeIconButton_Click() method:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ExchangeIconButton_Click(<span class="kwrd">object</span> sender, EventArgs e){   var viewModel = DataContext <span class="kwrd">as</span> MainViewModel;   <span class="kwrd">if</span> (viewModel == <span class="kwrd">null</span>)      <span class="kwrd">return</span>;   Focus();   Dispatcher.BeginInvoke(() =&gt;   {      <span class="kwrd">if</span> (!NetworkInterface.GetIsNetworkAvailable())      {         MessageBox.Show(            <span class="str">&quot;No network connection found!&quot;</span>,             <span class="str">&quot;Error&quot;</span>,             MessageBoxButton.OK);         <span class="kwrd">return</span>;      }      viewModel.ExchangeCurrency();   });}</pre><p>&nbsp;</p><p>This method will check for a valid MainViewModel set on the DataContext, remove the Focus from any TextBox (thus hiding the on-screen keyboard), check if there is a valid network connection, and then call the MainViewModel.ExchangeCurrency() method.</p><h2>Tombstoning</h2><p>The final piece to developing this into the perfect Windows Phone 7 application is making it “Tombstoning” aware!</p><p>Since WP7 doesn't allow multitasking, every time an application is deactivated or closed you should save its state and then restore it when the application is reactivated or reopened; this process is called “Tombstoning.”</p><p>To do this, we use the System.Runtime.Serialization classes, namely, the DataMemberAttribute to mark all the properties of the MainViewModel we want to save (FromCurrency, ToCurrency, and Amount), and the IgnoreDataMemberAttribute to mark the ones we don't (CurrencyExchangeService, Currencies, Result, ExchangedCurrency, and ExchangedAmount).</p><p>We can't (or at least, shouldn't!) directly save the state of the FromCurrency and ToCurrency properties because they have complex values (rather than a base type like Int or String), so we mark these with the IgnoreDataMemberAttribute and add two new properties, one for each, that will get/set the relative index of the Currencies array:</p><p><strong>C# <br></strong></p><pre class="csharpcode">[DataMember] <span class="kwrd">public</span> <span class="kwrd">int</span> FromCurrencyIndex{    get    {        <span class="kwrd">return</span> Array.IndexOf(Currencies, FromCurrency);    }    set    {        FromCurrency = Currencies[<span class="kwrd">value</span>];    }}[DataMember] <span class="kwrd">public</span> <span class="kwrd">int</span> ToCurrencyIndex{    get    {        <span class="kwrd">return</span> Array.IndexOf(Currencies, ToCurrency);    }    set    {        ToCurrency = Currencies[<span class="kwrd">value</span>];    }}</pre><p>&nbsp;</p><p>Now add the methods to Load and Save the state of the MainViewModel instance; since the Save method has to be called on the App.xaml.cs Application_Deactivated() and Application_Closing() events, the best way is to make our View Model a singleton. To do this, add the following code to the MainViewModel class:</p><p><strong>C# <br></strong></p><pre class="csharpcode">[IgnoreDataMember] <span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> SettingFileName = <span class="str">&quot;mainviewmodel.dat&quot;</span>; <span class="kwrd">public</span> <span class="kwrd">static</span> MainViewModel Instance { get; <span class="kwrd">protected</span> set; } <span class="kwrd">static</span> MainViewModel(){    Instance = Load();} <span class="kwrd">public</span> <span class="kwrd">static</span> MainViewModel Load(){    <span class="kwrd">return</span> StorageHelper.LoadContract&lt;MainViewModel&gt;(SettingFileName, <span class="kwrd">true</span>);} <span class="kwrd">public</span> <span class="kwrd">void</span> Save(){    StorageHelper.SaveContract(SettingFileName, <span class="kwrd">this</span>, <span class="kwrd">true</span>);}</pre><p>&nbsp;</p><p>The StorageHelper class you see here is just a helper used to serialize and deserialize a file on the application's IsolatedStorage.</p><p>Now all we have to do is change the MainPage.xaml.cs constructor so it uses the singleton instead of creating a new MainViewModel instance:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">public</span> MainPage(){    InitializeComponent();    <span class="kwrd">this</span>.DataContext = MainViewModel.Instance;}</pre><p>&nbsp;</p><p>Finally, invoke the Save method on the two required events of the App.xaml.cs file:</p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Application_Deactivated(<span class="kwrd">object</span> sender, DeactivatedEventArgs e){    MainViewModel.Instance.Save();} <span class="kwrd">private</span> <span class="kwrd">void</span> Application_Closing(<span class="kwrd">object</span> sender, ClosingEventArgs e){    MainViewModel.Instance.Save();}</pre><p>&nbsp;</p><p>And that is it! To test the application, open it, press the windows key so that the Windows Phone main screen appears, wait a couple of seconds, and press the back key to return to the application: you will see a “resuming” message appear when the application state restores!</p><p>The application can now be Tombstoned anytime, and when it gets opened again, it will appear as if it never closed!</p><h2>Conclusion</h2><p>As you see here, you can build simple applications for Windows Phone 7 by using basic MVVM architecture, and still have time to go out and have a coffee with your friends!</p><p>Remember: If you want to try this out, the download link for the source code is at the top of the article!</p><p>The sample code uses the BingCurrencyExchangeService, but it also has a second provider for MSN Money, the MsnMoneyCurrencyExchangeService, which you can check out!</p><h2>About The Author</h2><p>Pedro Lamas is a Portuguese .Net Senior Developer on Microsoft's Partner DevScope, where he works with all the cool stuff that Microsoft .Net has to offer its developers!</p><p>He's also one of the administrators of PocketPT.net, the largest Windows Phone Portuguese community, where his contribution is mostly visible on support for Windows Phone developers, and as a speaker for Windows Phone Development in Microsoft Portugal Events.</p><p>You can read his <a href="http://www.pedrolamas.com">blog</a> or contact him via <a href="http://twitter.com/pedrolamas">twitter</a>!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c06ad9bf51dc4c27a50c9e7600c7076d">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-for-Windows-Phone-7</comments>
      <itunes:summary> The purpose of this article is to show how you can make your very own, very simple Currency Converter application for Windows Phone 7, using Bing to make all the hard exchanging work!IntroductionMicrosoft has done an absolutely amazing job with the Windows Phone 7, giving each and every one of us all of the necessary tools to make our applications blend nicely on it; and the best part—the tools are, and will always be, free!!! JUsing Bing for the currency exchangeFirst let&#39;s look at what happens when I open up Bing on my browser, and enter a search query like “1 US Dollar in Euros”:As you can see, Bing correctly understood my query, and knew that I was looking for an exchange rate. Then MSN Money made the exchange and presented the result.Also, notice that the address displays as:http://www.bing.com/search?q=1&amp;#43;US&amp;#43;Dollar&amp;#43;in&amp;#43;Euros&amp;amp;go=&amp;amp;form=QBRE&amp;amp;qs=n&amp;amp;sk=&amp;amp;sc=1-20OK, but how can we use this to feed the WP7 application? Call the Internet Explorer Developer Tools (just press F12 on your IE8&amp;#43;) and use the “Select element by click” option (Ctrl &amp;#43; B) to select the result on the page and see its HTML code. The result will look just like this:Now we know how to build the Bing currency exchange search query (using “http://www.bing.com/search?q={VALUE}&amp;#43;{SOURCE_CURRENCY}&amp;#43;in&amp;#43;{DESTINATION_CURRENCY}&amp;amp;go=&amp;amp;form=QBRE&amp;amp;qs=n&amp;amp;sk=&amp;amp;sc=1-20”) and also how to find the results on the returned HTML (search the “&amp;lt;span class=&amp;quot;sc_bigLine&amp;quot;&amp;gt;RESULT&amp;lt;/span&amp;gt;”).The final task is selecting that span tag on the full HTML and then extracting the converted amount; for this task, I&#39;ll be using the following Regular Expression (using System.Text.RegularExpressions):C# static Regex _resultRegex =   new Regex(&amp;quot;&amp;lt;span class=\&amp;quot;sc_bigLine\&amp;quot;&amp;gt;.*? = (?&amp;lt;value&amp;gt;[0-9.,]&amp;#43;).*?&amp;lt;/span&amp;gt;&amp;quot;);&amp;nbsp;This expression searches the HTML code for a span with class “sc_bigLine” and inner content matchin</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-for-Windows-Phone-7</link>
      <pubDate>Tue, 30 Nov 2010 23:51:54 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Currency-Converter-for-Windows-Phone-7</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10098706_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10098706_220.jpg" height="165" width="220"/>      
      <dc:creator>Pedro Lamas</dc:creator>
      <itunes:author>Pedro Lamas</itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Currency-Converter-for-Windows-Phone-7/RSS</wfw:commentRss>
      <category>MVVM</category>
      <category>Silverlight</category>
      <category>Web Services</category>
      <category>XAML</category>
    </item>
  <item>
      <title>PicFx – Windows Phone Picture Effects Application – Part 2</title>
      <description><![CDATA[ <p>The <a href="http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-1">first part</a> of this short series showed how to create the base Windows Phone application and how to implement a Black &amp; White and Sepia effect. The basic Windows Phone picture manipulation workflow was explained, and I showed how to load, resize, take, and save an image. The User Interface with the Pivot control template was introduced and some important Windows Phone development key points were also discussed. We also learned how to implement the Black &amp; White and the Sepia effect with the reusable Tint and Contrast &amp; Brightness modification effects.</p><p>In this second, final part of the series, we will learn how to make the application more responsive by offloading the image processing computation to a background thread. Furthermore, how to implement a nice vintage Polaroid-like and a miniature faking (tilt shift) effect will be demonstrated, along with how to brand the finished image with a custom logo.</p><h2>The App in Action</h2><p>The video below introduces the complete PicFx application features and demonstrates how to use them. It was recorded with the application running in the emulator.</p><div><div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:53b060cc-d9d8-4313-a74a-f96c42cc686b" class="wlWriterEditableSmartContent"><div><object width="400" height="220"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=13599999&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=13599999&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="220"></embed></object><p><a href="http://vimeo.com/13599999">from Vimeo</a>.</p></div></div></div><p>Background music is “<a href="http://softphase.org/netlabel/releases/sfp12">A Silent Goodbye</a>” by NCThompson</p><h2>How it works</h2><p>In the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">last article</a>, we drilled down from the UI Crust with the Pivot control template and the Windows Phone Application Bar through the UI Mantle with the UI functionality until we finally reached the Effects Core with the image processing algorithms. </p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb.png" border="0" alt="image" width="220" height="234"></a></p><h2>The User Interface</h2><p>As in the first part, we again start our journey on the surface of the application.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_3.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_3.png" border="0" alt="image" width="221" height="234"></a></p><p>Some things have changed on the surface of the app—it still uses the Windows Phone <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.applicationbar(VS.92).aspx%5e">Application Bar</a>, but the <a href="http://phone.codeplex.com">open source Pivot control implementation from CodePlex</a> was replaced by the <a href="http://developer.windowsphone.com/windows-phone-7/">official control</a> from Microsoft. The WrapPanel from the official <a href="http://silverlight.codeplex.com/">Silverlight for Windows Phone Toolkit</a> is now also used. As you can see in Figure 1, thumbnails of the two new effects are shown on the second Pivot page.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_4.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_5.png" border="0" alt="image" width="509" height="529"></a><br><strong>Figure 1: The Pivot layout of the extented PicFx application</strong></p><p>The current MainPage.xaml:<strong>&nbsp;</strong></p><p><strong>XAML</strong><br><pre class="brush: xml">&lt;phoneCtrls:Pivot Name=&quot;PivotCtrl&quot; Title=&quot;PicFx&quot; &gt;   &lt;phoneCtrls:PivotItem Name=&quot;PivotItemPic&quot; Header=&quot;Pic&quot; &gt;
      &lt;Grid Height=&quot;510&quot; VerticalAlignment=&quot;Top&quot; &gt;
         &lt;Image Name=&quot;Viewport&quot; Stretch=&quot;Uniform&quot; /&gt;
         &lt;ProgressBar Name=&quot;ProgessBar&quot; 
             IsIndeterminate=&quot;True&quot; 
             Height=&quot;20&quot; Width=&quot;200&quot; 
                     Visibility=&quot;Collapsed&quot; 
                     HorizontalAlignment=&quot;Center&quot; 
                     VerticalAlignment=&quot;Center&quot; 
                     /&gt;
      &lt;/Grid&gt;
   &lt;/phoneCtrls:PivotItem&gt;   &lt;phoneCtrls:PivotItem  Name=&quot;PivotItemFx&quot; Header=&quot;Effects&quot; &gt;
      &lt;phoneCtrls:PivotItem.Resources&gt;
         &lt;vm:EffectItems x:Key=&quot;effects&quot;/&gt;
      &lt;/phoneCtrls:PivotItem.Resources&gt;
      &lt;ListBox Name=&quot;ListBoxEffects&quot; SelectionMode=&quot;Single&quot; 
                              ItemsSource=&quot;{StaticResource effects}&quot; 
                              SelectionChanged=&quot;ListBox_SelectionChanged&quot; &gt;
         &lt;ListBox.ItemsPanel&gt;
            &lt;ItemsPanelTemplate&gt;
               &lt;controlsToolkit:WrapPanel Width=&quot;480&quot; /&gt;
            &lt;/ItemsPanelTemplate&gt;
         &lt;/ListBox.ItemsPanel&gt;
         &lt;ListBox.ItemTemplate&gt;
           &lt;DataTemplate&gt;
              &lt;StackPanel Orientation=&quot;Vertical&quot; Margin=&quot;14&quot; &gt;
                &lt;Image Source=&quot;{Binding Thumbnail}&quot; Width=&quot;128&quot; Height=&quot;128&quot; /&gt;
                &lt;TextBlock Text=&quot;{Binding Name}&quot; 
                          FontSize=&quot;{StaticResource PhoneFontSizeNormal}&quot; 
                          VerticalAlignment=&quot;Center&quot; 
                           HorizontalAlignment=&quot;Center&quot; /&gt;
               &lt;/StackPanel&gt;
            &lt;/DataTemplate&gt;
         &lt;/ListBox.ItemTemplate&gt;
      &lt;/ListBox&gt;
   &lt;/phoneCtrls:PivotItem&gt;
         
&lt;/phoneCtrls:PivotControl&gt;</pre></p><p>An <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar.isindeterminate(v=VS.95).aspx">Indeterminate</a> <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar(VS.95).aspx">ProgressBar</a> was added to the first Pivot item overlaying the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image(VS.95).aspx">Image</a>, which shows the selected picture. The ProgressBar is hidden by default and only made visible when the picture with the full resolution is processed and saved.</p><p>The <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox(VS.95).aspx">ListBox</a> with the thumbnails of the effects (see Figure 1) is still data-bound to the StaticResource “effects,” an instance of the EffectItems class that consists of EffectItem elements:</p><p><strong>C#</strong><br><pre class="brush: csharp">public class EffectItems : ObservableCollection&lt;EffectItem&gt;
{
   public EffectItems()
   {
      Add(
            new EffectItem(new BlackWhiteEffect(), 
               &quot;data/icons/BlackWhite.png&quot;));
      Add(
         new EffectItem(new SepiaEffect(), 
            &quot;data/icons/Sepia.png&quot;));
      Add(
         new EffectItem(new TiltShiftEffect(), 
            &quot;data/icons/TiltShift.png&quot;));
      Add(
         new EffectItem(new PolaroidEffect(), 
            &quot;data/icons/PolaYellow.png&quot;, &quot;Pola&quot;));
   }
}
</pre></p><p>The two new EffectItems are added and the vintage Polaroid-like effect gets a custom display name—“Pola”—to avoid a mix-up with the original <a href="http://en.wikipedia.org/wiki/Polaroid_Corporation">Polaroid brand</a>.</p><p>I also added Clint Rutkas' Coding4Fun About control as an Application Bar menu item. This control is a typical about page which provides some information about the app and Coding4Fun.</p><p><strong>XAML </strong><br><pre class="brush: xml">&lt;phone:PhoneApplicationPage.ApplicationBar&gt;
    &lt;shell:ApplicationBar IsVisible=&quot;True&quot;&gt;
        &lt;shell:ApplicationBarIconButton Text=&quot;Choose&quot; 
            IconUri=&quot;/data/appbar/appbar.folder.rest.png&quot; 
            Click=&quot;ApplicationBarIconFolderButton_Click&quot;/&gt;
        &lt;shell:ApplicationBarIconButton Text=&quot;Take&quot; 
            IconUri=&quot;/data/appbar/appbar.feature.camera.rest.png&quot; 
            Click=&quot;ApplicationBarIconCameraButton_Click&quot;/&gt;
        &lt;shell:ApplicationBarIconButton Text=&quot;Save&quot; 
            IconUri=&quot;/data/appbar/appbar.save.rest.png&quot; 
            Click=&quot;ApplicationBarIconSaveButton_Click&quot;/&gt;
        &lt;shell:ApplicationBar.MenuItems&gt;
            &lt;shell:ApplicationBarMenuItem Text=&quot;About&quot; 
               Click=&quot;ApplicationBarMenuItemAbout_Click&quot; /&gt;
        &lt;/shell:ApplicationBar.MenuItems&gt;
    &lt;/shell:ApplicationBar&gt;
&lt;/phone:PhoneApplicationPage.ApplicationBar&gt;</pre></p><h2>The Code Behind</h2><p>The <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a> introduced the Windows Phone picture manipulation workflow and explained how to load, resize, take, and save an image. This section will show how to keep the UI responsive by performing the image processing asynchronously. </p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_5.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_6.png" border="0" alt="image" width="228" height="234"></a></p><p>The two new effects introduced in this article are more computationally expensive. If these would be applied to the original sized picture, the UI thread would get blocked for a few seconds. This is a No Go for a professional application and in order to pass the Marketplace validation, an app has to be responsive and needs to avoid hang-ups. This and other important requirements are defined in the official <a href="http://go.microsoft.com/?linkid=9730558">Windows Phone 7 Application Certification Requirements</a> document. </p><h3>Asynchronous Processing</h3><p>To achieve a good responsiveness of the application, the work has to be offloaded from the UI thread to a background thread. Here is where Silverlight's multi-threading strength comes into play. </p><p>There is only one problem—due to its base classes, the <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx">WriteableBitmap</a> can't be used in a non-UI thread. As we know from the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first article</a>, the <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap%28VS.95%29.aspx">WriteableBitmap</a> uses the <a href="http://en.wikipedia.org/wiki/Rgb">RGB color space</a> to represent the pixels. It's actually just a 32-bit integer array that stores the alpha, red, green, and blue (ARGB) byte components for all the pixels in a 1D array, and stores the width and the height as integer properties. This leads us to the natural solution: perform the whole cascade of image processing effects with an integer array (pixels) along with the width and height and only copy the final result back to WriteableBitmap on the UI thread.</p><p>No sooner said than done, the following code is executed when the user hits the Save button:</p><p><strong>C#</strong><br><pre class="brush: csharp">if (ListBoxEffects.SelectedItem == null)
{
   return;
}// Set Save.. state and get UI parameters
Viewport.Opacity = 0.2;
ProgessBar.Visibility = Visibility.Visible;
var effect = ((EffectItem)ListBoxEffects.SelectedItem).Effect;
var dispatcher = Dispatcher;ThreadPool.QueueUserWorkItem((state) =&gt;
{
   try
   {
      // Apply Effect on int[] since WriteableBitmap 
      // can't be used in background thread
      var width = original.PixelWidth;
      var height = original.PixelHeight;
      var resultPixels = effect.Process(original.Pixels, width, height);      // Convert int[] to WriteabelBitmap
      // WriteableBitmap ctor has to be invoked on the UI thread
      dispatcher.BeginInvoke(() =&gt;
      {
         // Turbo copy the pixels to the WriteableBitmap
         var result = new WriteableBitmap(width, height);
         Buffer.BlockCopy(resultPixels, 
        0, 
        result.Pixels, 
        0, 
        resultPixels.Length * 4);
         
         // Save WriteableBitmap
         var name = String.Format(
        &quot;PicFx_{0:yyyy-MM-dd_hh-mm-ss-tt}.jpg&quot;, 
        DateTime.Now);
         result.SaveToMediaLibrary(name);
      });
   }
   finally
   {
      // Set controls to initial state
      dispatcher.BeginInvoke(() =&gt;
      {
         ProgessBar.Visibility = Visibility.Collapsed;
         Viewport.Opacity = 1;
      });
   }
});</pre></p><p>The ProgressBar is shown during the asynchronous processing and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.opacity(v=VS.95).aspx">Opacity</a> of the Image control is reduced (Figure 2). The actual image processing with the selected effect is performed on a background thread. Using the <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool(VS.95).aspx">ThreadPool</a> class and its <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem(v=VS.95).aspx">QueueUserWorkItem</a> method accomplishes this. The ThreadPool provides a pool of <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)">threads</a> and the QueueUserWorkItem is used to queue a work operation for processing. The main benefit is that resources aren't unnecessarily hogged—the creation of a thread takes some time and each thread needs certain resources such as its own memory stack. Also note that, for common computational scenarios, it's best to keep a balance between threads and processor cores. A thread pool avoids the creation overhead through a certain amount of threads that are kept alive and all the queued work is executed one after another by these threads.</p><p>The IEffect's new Process method overload with the pixels integer array and size parameters is used inside the background thread processing. Read more about the IEffect interface change below.</p><p>After the effects processing chain is done, a new WriteableBitmap is then instantiated on the UI thread with the use of the Page's <a href="http://msdn.microsoft.com/en-us/library/ms615907(v=VS.95).aspx">Dispatcher</a>, which executes code on the UI thread. Then the integer pixels array is copied to the WriteableBitmap's <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.pixels(v=VS.95).aspx">Pixels</a> property with the fast <a href="http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy(v=VS.95).aspx">BlockCopy</a>. The BlockCopy method copies a block of bytes in one single operation in memory, just like the good ol' <a href="http://msdn.microsoft.com/en-us/library/dswaw1wk(VS.71).aspx">memcpy</a>.</p><p>The final bitmap is then saved to the picture library/photo album with the SaveToMediaLibrary extension method that was introduced in the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a>. Finally, the ProgessBar is again hidden and the Image's opacity is restored.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_6.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_7.png" border="0" alt="image" width="289" height="531"></a></p><p><strong>Figure 2: Saving a picure shows the ProgressBar over the semi-transparent Image</strong></p><h2>The Effects</h2><p>Now that we made the image processing asynchronous and the UI is responsive even when complex computations are performed, it's time to leverage this feature for some advanced effects.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_7.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_8.png" border="0" alt="image" width="221" height="234"></a></p><p>The IEffect interface had to be changed for the asynchronous WriteableBitmap-less processing. The new Process method overload expects the pixels as ARGB32 integer array, and the width and height of the bitmap as parameters. The return value is the processed bitmap as integer pixel array of the same size.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_8.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_9.png" border="0" alt="image" width="331" height="186"></a><strong><br>Figure 3: The changed IEffect interface</strong></p><p>As we learned in the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a>, the end user effects are called composite effects (outer core), which are made out of various, reusable base effects (inner core).</p><h2>The Vintage Polaroid-like Effect</h2><p>This composite effect gives a picture an old-touch so it looks like it was taken with an old, Polaroid-like camera.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_9.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_10.png" border="0" alt="image" width="289" height="531"></a></p><p><strong>Figure 4: Vintage Polaroid-like effect applied to the sample picture</strong></p><p>The Polaroid-like composite effect uses three internal base effects: a Gaussian blur, an effect that adds a black vignette, and the Tint base effects introduced in the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a> (Figure 5). </p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_10.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_11.png" border="0" alt="image" width="619" height="312"></a><strong><br>Figure 5: The class diagram of the PolaroidEffect</strong></p><p>Old photos weren't as sharp as modern photos and therefore the Blurriness property defines how much the picture will be blurred. The Vignette property controls the size of the round vignette. Additionally, the amount of tinting and the tint color can be changed with properties.</p><p><strong>C#</strong><br><pre class="brush: csharp">public class PolaroidEffect : IEffect
{
   readonly GaussianBlurEffect blurFx;
   readonly VignetteEffect vignetteFx;
   readonly TintEffect tintFx;
   readonly BitmapMixer mixer;   public string Name { get { return &quot;Vintage&quot;; } }   public float Blurriness 
   {
      get { return blurFx.Sigma; }
      set { blurFx.Sigma = value; }
   }   public float Vignette
   {
      get { return vignetteFx.Size; }
      set { vignetteFx.Size = value; }
   }   public float Tinting
   {
      get { return mixer.Mixture; }
      set { mixer.Mixture = value; }
   }   public Color TintColor
   {
      get { return tintFx.Color; }
      set { tintFx.Color = value; }
   }   public PolaroidEffect()
   {
      blurFx = new GaussianBlurEffect { Sigma = 0.15f };
      vignetteFx = new VignetteEffect();
      tintFx = TintEffect.Sepia;
      mixer = new BitmapMixer { Mixture = 0.5f };
   }   public WriteableBitmap Process(WriteableBitmap input)
   {
      var width = input.PixelWidth;
      var height = input.PixelHeight;
      return Process(input.Pixels, width, height)
          .ToWriteableBitmap(width, height);
   }   public int[] Process(int[] inputPixels, int width, int height)
   {
      var resultPixels = blurFx.Process(inputPixels, width, height);
      resultPixels = vignetteFx.Process(resultPixels, width, height);
      var tintedPixels = tintFx.Process(resultPixels, width, height);
      return mixer.Mix(resultPixels, tintedPixels, width, height);
   }
}</pre></p><p>First the input is blurred and the vignette is added. Afterward, a new Sepia-tinted version of the processed image is created. In the last processing step, the non-tinted and the tinted bitmap are mixed together with the use of the new BitmapMixer class. This results in a slight Sepia tint rather than the full Sepia tone.</p><h2>The New Base Effects</h2><p>The vintage Polaroid-like effect uses three base effects and a mixer to achieve the old look. Now it's time to see how its Inner Core effects work.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_11.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_12.png" border="0" alt="image" width="221" height="234"></a></p><h3>The Blur Effect</h3><p>There are several different available <a href="http://en.wikipedia.org/wiki/Blur">blur</a> algorithms, and one of the most common is the <a href="http://en.wikipedia.org/wiki/Gaussian_blur">Gaussian blur</a>. The Gaussian blur applies a <a href="http://en.wikipedia.org/wiki/Gaussian_function">Gaussian function</a> to an image in order to smooth it and reduce details. The naïve implementation uses a <a href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/kernel.htm">convolution kernel</a>, which is basically a 2D array of <em>n</em> x <em>n</em> elements. In the case of a Gaussian filter the kernel values represent a discrete 2D <a href="http://en.wikipedia.org/wiki/Gaussian_function">Gaussian function</a>, which has the typical <a href="http://en.wikipedia.org/wiki/Gaussian_filter">bell shape</a>. The usual kernel has a size of 5 x 5, though other kernels range from 7 x 7 on up.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_12.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_13.png" border="0" alt="image" width="304" height="332"></a><br><strong>Figure 6: Gaussian blur applied to the sample image</strong></p><p>During the actual image processing, a pixel of the input image is multiplied with all of the kernel elements. The products of the pixel-kernel-element multiplication are summed and divided, and then the result is assigned as the output pixel. This is done for all the pixels of the input image. </p><p>The disadvantage of this approach is that the computation time increases when the blurring is increased. In order to blur the image more, the kernel size is usually enlarged, thus meaning <em>n</em> x <em>n</em> multiplications need to be performed for each pixel. Fortunately, in 1995 Ian T. Young and Lucas J. van Vliet invented a better algorithm that is independent of the width. They describe the method in detail in their paper, “<a href="http://www.bing.com/search?q=%22Recursive&#43;implementation&#43;of&#43;the&#43;Gaussian&#43;filter%22">Recursive implementation of the Gaussian filter</a>.”</p><p>It gets even better—<a href="http://www.planetmarshall.co.uk/about/">Andrew Marshall</a> already implemented the recursive Gaussian filter in C# for his <a href="http://www.planetmarshall.co.uk/2010/01/silverlight-and-cuda-interop/">Silverlight and CUDA interop</a> blog post and allowed me the use it. As you can imagine, the implementation is quite complex and could make up an article on its own. In fact, Young &amp; van Vliet already wrote this article by writing their paper. Please read it if you want to know the mathematical details behind the GaussianBlurEffect class.</p><h3>The Vignette Effect</h3><p>The effect of <a href="http://en.wikipedia.org/wiki/Vignetting">vignetting</a> reduces the brightness of the pixels towards the edges. This is done by computing the pixel's distance to the center and multiplying this with the pixel color. This generates the vignette effect as a fadeout to black towards the edges.</p><p><strong>&nbsp;</strong></p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_13.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_14.png" border="0" alt="image" width="308" height="335"></a><br><strong>Figure 7: A black vignette</strong></p><p>The Process method of the VignetteEffect implements the vignetting.</p><p><strong>C#</strong><br><pre class="brush: csharp">public int[] Process(int[] inputPixels, int width, int height)
{
   // Prepare some variables
   var resultPixels = new int[inputPixels.Length];
   var ratio = width &gt; height ? 
      height * 32768 / width : 
      width * 32768 / height;   // Calculate center, min and max
   var cx = width &gt;&gt; 1;
   var cy = height &gt;&gt; 1;
   var max = cx * cx &#43; cy * cy;
   var min = (int)(max * (1 - Size));
   var diff = max - min;   var index = 0;
   for (int y = 0; y &lt; height; y&#43;&#43;)
   {
      for (int x = 0; x &lt; width; x&#43;&#43;)
      {
         var c = inputPixels[index];         // Extract color components
         var a = (byte)(c &gt;&gt; 24);
         var r = (byte)(c &gt;&gt; 16);
         var g = (byte)(c &gt;&gt; 8);
         var b = (byte)(c);         // Calculate distance to center 
         // and adapt aspect ratio
         var dx = cx - x;
         var dy = cy - y;
         if (width &gt; height)
         {
            dx = (dx * ratio) &gt;&gt; 15;
         }
         else
         {
            dy = (dy * ratio) &gt;&gt; 15;
         }
         int distSq = dx * dx &#43; dy * dy;         if (distSq &gt; min)
         {
            // Calculate vignette
            var v = ((max - distSq) &lt;&lt; 8) / diff;
            v *= v;            // Apply vignette
            var ri = (r * v) &gt;&gt; 16;
            var gi = (g * v) &gt;&gt; 16;
            var bi = (b * v) &gt;&gt; 16;            // Check bounds
            r = (byte)(ri &gt; 255 ? 
              255 : 
              (ri &lt; 0 ? 0 : ri));
            g = (byte)(gi &gt; 255 ? 
              255 : 
              (gi &lt; 0 ? 0 : gi));
            b = (byte)(bi &gt; 255 ? 
              255 : 
              (bi &lt; 0 ? 0 : bi));            // Combine components
            c = (a &lt;&lt; 24) | 
               (r &lt;&lt; 16) | 
               (g &lt;&lt; 8) | 
               b;
         }         resultPixels[index] = c;
         index&#43;&#43;;
      }
   }   return resultPixels;
}</pre></p><p>The x and y coordinate of the image's center and the aspect ratio are calculated. As you can see, only fast integer operations are used again. </p><p>Inside the loop, the color components of each input pixel are extracted and the distance vector to the center is calculated with respect to the picture's aspect ratio. The squared length of the distance vector is tested against the minimum vignette size. If the pixel falls within the range, the scaled distance length is multiplied with each color component. The result is an adapted brightness as described above. The last step ensures that the color components are in the byte range and then combines these to the result integer pixel color.</p><h3>The BitmapMixer</h3><p>As the name might imply, the purpose of the BitmapMixer class is to mix two images. The Mix method mixes two ARGB32 integer bitmaps of the same size and returns the mixed bitmap. This is actually an <a href="http://en.wikipedia.org/wiki/Alpha_compositing">alpha blending</a> operation where the Mixture property defines the opacity of the input2 image. A Mixture value of 0 means input1 is fully visible and a value of 1 means that input2 is shown—everything in between is a mix of both.</p><p><strong>C#</strong><br><pre class="brush: csharp">public float Mixture { get; set; }public int[] Mix(int[] inputPixels1, 
   int[] inputPixels2, 
   int width, 
   int height)
{
   // Prepare some variables
   var resultPixels = new int[inputPixels1.Length];
   var m = Mixture;
   var mi = 1 - m;   for (var i = 0; i &lt; inputPixels1.Length; i&#43;&#43;)
   {
      // Extract color components
      var c1 = inputPixels1[i];
      var a1 = (byte)(c1 &gt;&gt; 24);
      var r1 = (byte)(c1 &gt;&gt; 16);
      var g1 = (byte)(c1 &gt;&gt; 8);
      var b1 = (byte)(c1);      var c2 = inputPixels2[i];
      var a2 = (byte)(c2 &gt;&gt; 24);
      var r2 = (byte)(c2 &gt;&gt; 16);
      var g2 = (byte)(c2 &gt;&gt; 8);
      var b2 = (byte)(c2);      // Mix it!
      var d = ((byte)(a1 * mi &#43; a2 * m) &lt;&lt; 24) |
              ((byte)(r1 * mi &#43; r2 * m) &lt;&lt; 16) |
              ((byte)(g1 * mi &#43; g2 * m) &lt;&lt; 8) |
              ((byte)(b1 * mi &#43; b2 * m));      // Set result color
      resultPixels[i] = d;
   }   return resultPixels;
}</pre></p><p>The color components of the two input images are extracted. Each color component of input2 is then multiplied with the Mixture factor and input2 is multiplied with the inverse of the Mixture. Then, both color component products are added and the new values are combined to form the new integer output pixel.</p><h3>The Tilt Shift Effect</h3><p>Now that we've learned the details of some of the new Inner Core effects, it's time to use some of them in a different combination and make an interesting Outer Core effect.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_14.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_15.png" border="0" alt="image" width="221" height="234"></a></p><p>The digital <a href="http://en.wikipedia.org/wiki/Tilt-shift_photography">tilt shift</a> effect lets a scene look like a miniature scale model. It's quite popular nowadays and you might have seen it applied to video in some ads. It's commonly called <a href="http://en.wikipedia.org/wiki/Miniature_faking">miniature faking</a> and produces a nice result if it's applied to a photo that was taken from a high angle.</p><p>&nbsp;</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_15.png"><strong><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_16.png" border="0" alt="image" width="289" height="526"></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_16.png"><strong><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_17.png" border="0" alt="image" width="209" height="155"></strong></a></p><p><strong><br>Figure 8: The tilt shift Effect applied to a photo of Dresden that I have taken from a Ferris wheel</strong></p><p>In the first processing stage the TiltShiftEffect increases the contrast of the image with the BrightnessContrastModification effect, which was introduced in the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a>. Afterward, the picture gets blurred with the GaussianBlurEffect. The blurred version is then combined with the non-blurred to produce the shallow <a href="http://en.wikipedia.org/wiki/Depth_of_field">depth of field</a> of a close-up shot.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_17.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_18.png" border="0" alt="image" width="619" height="438"></a><strong><br>Figure 9: The class diagram of the TiltShiftEffect</strong></p><p>The UpperFallOff property defines the relative y coordinate where the depth of field (camera focus) is completely faded out. The LowerFadeOff defines the lower focus counterpart:</p><p><strong>C#</strong><br><pre class="brush: csharp">public float UpperFallOff { get; set; }
public float LowerFallOff { get; set; }private int[] contrastedPixels;
private int[] blurredPixels;public int[] Process(
   int[] inputPixels, 
   int width, 
   int height)
{
   // Increase contrast
   CreateBlurredBitmap(inputPixels, width, height);   // Mix the fade off
   return ProcessOnlyFocusFadeOff(
      inputPixels, 
      width, 
      height);
}private void CreateBlurredBitmap(
   int[] inputPixels, 
   int width, 
   int height)
{
   // Increase contrast
   contrastedPixels = contrastFx.Process(
      inputPixels, 
      width, 
      height);   // Blur 
   blurredPixels = blurFx.Process(
                              contrastedPixels, 
                              width, 
                              height);
}public int[] ProcessOnlyFocusFadeOff(
   int[] inputPixels, 
   int width, 
   int height)
{
   // Check if the cache is empty
   if (contrastedPixels == null || blurredPixels == null)
   {
      CreateBlurredBitmap(inputPixels, width, height);
   }   var resultPixels = blurredPixels;   // If not fully blurred?
   if (UpperFallOff &lt; LowerFallOff)
   {
      // Prepare some variables
      resultPixels = new int[inputPixels.Length];      // Calculate fade area
      var uf = (int)(UpperFallOff * height);
      var lf = (int)(LowerFallOff * height);
      var fo = ((lf - uf) &gt;&gt; 1);
      var mf = uf &#43; fo;
      var mfu = mf;
      var mfl = mf;      // Limit fall off and calc inverse
      if (fo &gt; height * MaxFallOffFactor)
      {
         fo = (int)(height * MaxFallOffFactor);
         mfu = uf &#43; fo;
         mfl = lf - fo;
      }
      var ifo = 1f / fo;
      // Blend
      var index = 0;
      for (var y = 0; y &lt; height; y&#43;&#43;)
      {
         for (var x = 0; x &lt; width; x&#43;&#43;)
         {
            var c2 = contrastedPixels[index];            // Above or below the fading area
            if (y &lt; mfu || y &gt; mfl)
            {
               var c = blurredPixels[index];               // Inside the fading area, 
               // but not in the focused area
               if (y &gt; uf || y &lt; lf)
               {
                  // Extract color components
                  var a1 = (byte)(c &gt;&gt; 24);
                  var r1 = (byte)(c &gt;&gt; 16);
                  var g1 = (byte)(c &gt;&gt; 8);
                  var b1 = (byte)(c);                  var a2 = (byte)(c2 &gt;&gt; 24);
                  var r2 = (byte)(c2 &gt;&gt; 16);
                  var g2 = (byte)(c2 &gt;&gt; 8);
                  var b2 = (byte)(c2);                  // Calculate blending
                  float m = y &lt; mf ? (mfu - y) : (y - mfl);
                  m *= ifo;
                  if (m &gt; 1)
                  {
                     m = 1f;
                  }
                  var mi = 1 - m;                  // Mix it!
                  c = ((byte)(a1 * m &#43; a2 * mi) &lt;&lt; 24) |
                        ((byte)(r1 * m &#43; r2 * mi) &lt;&lt; 16) |
                        ((byte)(g1 * m &#43; g2 * mi) &lt;&lt; 8) |
                        ((byte)(b1 * m &#43; b2 * mi));
               }               // Set result color
               resultPixels[index] = c;
            }
            else
            {
               resultPixels[index] = c2;
            }
            index&#43;&#43;;
         }
      }
   }   return resultPixels;
}</pre></p><p>As you can see, the processing is split into three methods and two member variables are used to cache both the contrast-increased result and the blurred result. This is useful when only the FallOff properties are changed interactively in real-time, which is described below.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_18.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_19.png" border="0" alt="image" width="306" height="332"></a><strong>&nbsp;</strong></p><p><strong>Figure 10: The simulated depth of field fade out</strong></p><p>The actual processing mixes the contrast-increased image and the blurred image by using a linear fading function. Figure 10 illustrates this. The red color represents the blurred version and the gray stands for the contrast-increased image. </p><p>This fading uses the FallOff properties, converts these properties into absolute values, and calculates some y coordinates, which are needed for the fade in/out. Inside the loop, the color components of both bitmaps are extracted and the mixture factor is computed. Then the color components are multiplied with the factors like in the BitmapMixer's Mix method. The last step combines the component results and sets the integer pixel of the result image.</p><h2>Multitouch Focus Fade Out Manipulation</h2><p>The Windows Phone is a nice multitouch device with very good usability. Its multitouch power is used in the PicFx app to let the user interactively change the FallOff properties of the TiltShiftEffect; therefore, the focused area can be altered in an intuitive way.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_19.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_20.png" border="0" alt="image" width="228" height="234"></a></p><p>Silverlight and the Windows Phone Silverlight version provide the static <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.touch(VS.95).aspx">Touch</a> class, which has only one member, the <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.touch.framereported(v=VS.95).aspx">FrameReported</a> event. This event is fired each time a set of touch points is registered. </p><p>An event handler is attached in the Initialize method of the MainPage. Please note that one would actually encapsulate the following code in a separate class like ViewModel for the effect, but I decided to leave this out to keep the code simpler and focused on the nitty gritty.</p><p><strong>C#</strong><br><pre class="brush: csharp">private void Initialize()
{
   // Attach touch event handler
   Touch.FrameReported &#43;= Touch_FrameReported;
   // ...
}private void Touch_FrameReported(
   object sender, 
   TouchFrameEventArgs e)
{
   SetTiltShiftFocus(e.GetTouchPoints(Viewport));
}private void SetTiltShiftFocus(IList&lt;TouchPoint&gt; points)
{
   IEffect effect = null;
   if (ListBoxEffects != null)
   {
      var item = ListBoxEffects.SelectedItem as EffectItem;
      if (item != null)
      {
         effect = item.Effect;
      }
   }   var tiltFx = effect as TiltShiftEffect;
   if (tiltFx == null)
   {
      return;
   }
   var result = Viewport.Source;
   var isManipulating = points.Any(
      p =&gt; p.Action == TouchAction.Down
                  || p.Action == TouchAction.Move);
   if (isManipulating)
   {
      if (points.Count &gt; 1)
      {
         var y1 = (int)points[0].Position.Y;
         var y2 = (int)points[1].Position.Y;         // FallOff is expected as relative coordinate
         var ih = 1f / resized.PixelHeight;         // Topmost point is upper FallOff
         if (y1 &lt; y2)
         {
            tiltFx.UpperFallOff = y1 * ih;
            tiltFx.LowerFallOff = y2 * ih;
         }
         else
         {
            tiltFx.UpperFallOff = y2 * ih;
            tiltFx.LowerFallOff = y1 * ih;
         }         // Apply selected effect
         var processed = 
            tiltFx.ProcessOnlyFocusFadeOff(resized);         // Add FallOff marker lines
         const int markerHeight = 4;
         processed.FillRectangle(
            0, 
            y1 - markerHeight,
            resized.PixelWidth,
            y1 &#43; markerHeight,
            Colors.LightGray);         processed.FillRectangle(
            0, 
            y2 - markerHeight, 
            resized.PixelWidth, 
            y2 &#43; markerHeight, 
            Colors.LightGray);         result = processed;
      }
   }
   else
   {
      // Apply selected effect
      result = tiltFx.Process(resized);
   }   // Show the result
   ShowImage(result);
}</pre></p><p>Every time the multitouch event is fired, the SetTiltShiftFocus method gets called. This method converts the absolute coordinates into relative and assigns the values to the appropriate properties. The topmost point is always interpreted as UpperFallOff.</p><p>Two small, gray rectangles are drawn at the position of the FallOff values to give the user some feedback. This is done with the <a href="http://writeablebitmapex.codeplex.com/">WriteableBitmapEx</a>' FillRectangle extension method. To keep the UI responsive, the ProcessOnlyFocusFadeOff method of the TiltShiftEffect is called, and this method uses the cached contrast-increased and blurred images by mixing them. This speeds the process up a lot up. </p><h2>The Watermark</h2><p>Now it's time to brand our final image with a custom logo before it gets saved. This watermark is useful to customize or add information to a photo.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_20.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_21.png" border="0" alt="image" width="309" height="334"></a></p><p><strong>Figure 11: Watermark logo applied to the sample image</strong></p><p>The Watermarker class has the Watermark property, which represents a WriteableBitmap that is used as watermark logo. The RelativeSize defines the size of the logo relative to the size of the input bitmap it should get applied to:</p><p><strong>C#</strong><br><pre class="brush: csharp">public class Watermarker
{
   public WriteableBitmap Watermark { get; private set; }
   public float RelativeSize { get; set; }   public Watermarker(string relativeResourcePath)
   {
      Watermark = new WriteableBitmap(0, 0)
         .FromResource(relativeResourcePath);      RelativeSize = 0.4f;
   }   public WriteableBitmap Apply(WriteableBitmap input)
   {
      // Resize watermark
      var w = Watermark.PixelWidth;
      var h = Watermark.PixelHeight;
      var ratio = (float) w / h;
      h = (int) (input.PixelHeight * RelativeSize);
      w = (int) (h * ratio);
      var watermark = Watermark.Resize(
         w, 
         h, 
         WriteableBitmapExtensions.Interpolation.Bilinear);      // Blit watermark into copy of the input 
      // Bottom right corner
      var result = input.Clone();
      var position = new Rect(
         input.PixelWidth - w, 
         input.PixelHeight - h, 
         w, 
         h);      result.Blit(position, watermark, new Rect(0, 0, w, h));      return result;
   }
}</pre></p><p>The constructor provides an easy way to pass a bitmap from the resource stream. In the Apply method, the watermark bitmap is scaled with the use of the <a href="http://writeablebitmapex.codeplex.com/">WriteableBitmapEx</a>' Resize method. After this the position is calculated, the watermark logo is <a href="http://en.wikipedia.org/wiki/Bit_blit">blitted</a> into the bottom right corner of the input image and the result is returned. Note that the <a href="http://writeablebitmapex.codeplex.com/">WriteableBitmapEx</a>' Blit method is used here.</p><p>An instance of the Watermarker class is created in the MainPage.xaml.cs.</p><p><strong>C#</strong><br><pre class="brush: csharp">private void Initialize()
{
   watermarker = new Watermarker(&quot;data/watermark.png&quot;);
   // ...
}private void ApplySelectedEffectAndSaveAsync()
{
   // ...
      // Turbo copy the pixels to the WriteableBitmap
      var result = new WriteableBitmap(width, height);
      Buffer.BlockCopy(
         resultPixels, 
         0, 
         result.Pixels, 
         0, 
         resultPixels.Length * 4);
      
      // Apply logo
      result = watermarker.Apply(result);      // Save WriteableBitmap
      var name = String.Format(
         &quot;PicFx_{0:yyyy-MM-dd_hh-mm-ss-tt}.jpg&quot;, 
         DateTime.Now);
      result.SaveToMediaLibrary(name);
   // ...
}</pre></p><p>The watermark is applied after the image processing was performed and before the picture gets saved to the media library.</p><h3>Conclusion</h3><p>In the <a href="http://blogs.msdn.com/b/coding4fun/archive/2010/08/09/10048007.aspx">first part</a> we drilled down from the UI Crust with the Pivot control template and the Windows Phone Application Bar through the UI Mantle. Finally we reached the Effects Core with the Black &amp; White, Sepia, BrightnessContrast, and Tint effects.</p><p>In this second part, we again journeyed to the core, starting on the surface in order to learn how to keep the UI responsive with asynchronous processing. We then entered the core and l explained the Polaroid-like vintage, its Gaussian blur, the Vignette effects, and the BitmapMixer. I also demonstrated the miniature faking Tilt Shift effect, including the multitouch manipulation of its parameters. The last step showed how to add a custom logo watermark to the final picture. </p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_21.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_22.png" border="0" alt="image" width="220" height="234"></a></p><p>This short series, or two articles, if you will, has come to end. Yep, it's over now—BUT Coding4Fun has released this development stage of the PicFx app for free on the Marketplace! Furthermore, I continued my work on this project and shipped it with enhanced effects, without watermark, but with extra features and a bunch of new effects, including essential ones like auto adjust, soften and many more. Check out the app called <a href="http://twitter.com/PicturesLab">Pictures Lab</a> aimed to be nothing less than THE image effects addition to the Windows Phone Pictures Hub.</p><h2>About The Author</h2><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_22.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10077086/image_thumb_23.png" border="0" alt="image" width="140" height="140" align="right"></a>René Schulte is a .Net, Silverlight and Windows Phone developer and Microsoft <a href="http://mvp.support.microsoft.com/profile/Rene.Schulte">Silverlight MVP</a> passionate about real-time computer graphics, physics, AI, and algorithms. He loves C#, Shaders, Augmented Reality, and computer vision. He started the <a href="http://SLARToolkit.codeplex.com">SLARToolkit</a>, the <a href="http://WriteableBitmapEx.codeplex.com">WriteableBitmapEx</a>, and the <a href="http://Matrix3DEx.codeplex.com">Matrix3DEx</a> Silverlight open source projects, and he has a <a href="http://rene-schulte.info">Silverlight website</a> powered by real time soft body physics. He is also a regular author for Microsoft's Coding4Fun. Contact information can be found on his <a href="http://rene-schulte.info">Silverlight website</a>, his <a href="http://blog.rene-schulte.info">blog</a>, or via <a href="http://twitter.com/rschu">Twitter</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:79d8e9f2692d48f280559e7600c77882">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-2</comments>
      <itunes:summary> The first part of this short series showed how to create the base Windows Phone application and how to implement a Black &amp;amp; White and Sepia effect. The basic Windows Phone picture manipulation workflow was explained, and I showed how to load, resize, take, and save an image. The User Interface with the Pivot control template was introduced and some important Windows Phone development key points were also discussed. We also learned how to implement the Black &amp;amp; White and the Sepia effect with the reusable Tint and Contrast &amp;amp; Brightness modification effects.In this second, final part of the series, we will learn how to make the application more responsive by offloading the image processing computation to a background thread. Furthermore, how to implement a nice vintage Polaroid-like and a miniature faking (tilt shift) effect will be demonstrated, along with how to brand the finished image with a custom logo.The App in ActionThe video below introduces the complete PicFx application features and demonstrates how to use them. It was recorded with the application running in the emulator.from Vimeo.Background music is “A Silent Goodbye” by NCThompsonHow it worksIn the last article, we drilled down from the UI Crust with the Pivot control template and the Windows Phone Application Bar through the UI Mantle with the UI functionality until we finally reached the Effects Core with the image processing algorithms. The User InterfaceAs in the first part, we again start our journey on the surface of the application.Some things have changed on the surface of the app—it still uses the Windows Phone Application Bar, but the open source Pivot control implementation from CodePlex was replaced by the official control from Microsoft. The WrapPanel from the official Silverlight for Windows Phone Toolkit is now also used. As you can see in Figure 1, thumbnails of the two new effects are shown on the second Pivot page.Figure 1: The Pivot layout of the extented PicFx applicationT</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-2</link>
      <pubDate>Tue, 19 Oct 2010 13:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-2</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10077086_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10077086_220.jpg" height="165" width="220"/>      
      <dc:creator>Rene Schulte</dc:creator>
      <itunes:author>Rene Schulte</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-2/RSS</wfw:commentRss>
      <category>Silveright</category>
      <category>Silverlight</category>
      <category>Windows Phone</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Three Reasons Developers Should Use Expression Blend</title>
      <description><![CDATA[ <p>Lots of developers are building XAML-based applications today.&nbsp; Be it WPF, Silverlight or Windows Phone 7, I have seen a lot of people struggle with certain tasks in Visual Studio that would be much easier if undertaken in Expression Blend.&nbsp; Blend seems to be somewhat intimidating to developers, especially those that are already wrestling with learning XAML. Having spent time in both tools, I can tell you that Blend can make three things dramatically easier, and you should learn how to do these three things with Blend, even if you never use it for anything else.</p><p><a href="http://s3.amazonaws.com/slickthought/Downloads/Code/DevelopersUseBlend.zip">Demo code</a></p><p>&nbsp;</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c1c12c831c7645eb8cc59e0f011f4bf9">]]></description>
      <comments>http://channel9.msdn.com/Blogs/SlickThought/Three-Reasons-Developers-Should-Use-Expression-Blend</comments>
      <itunes:summary> Lots of developers are building XAML-based applications today.&amp;nbsp; Be it WPF, Silverlight or Windows Phone 7, I have seen a lot of people struggle with certain tasks in Visual Studio that would be much easier if undertaken in Expression Blend.&amp;nbsp; Blend seems to be somewhat intimidating to developers, especially those that are already wrestling with learning XAML. Having spent time in both tools, I can tell you that Blend can make three things dramatically easier, and you should learn how to do these three things with Blend, even if you never use it for anything else.Demo code&amp;nbsp;</itunes:summary>
      <itunes:duration>838</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/SlickThought/Three-Reasons-Developers-Should-Use-Expression-Blend</link>
      <pubDate>Fri, 15 Oct 2010 18:35:16 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/SlickThought/Three-Reasons-Developers-Should-Use-Expression-Blend</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_100_ch9.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_220_ch9.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_512_ch9.jpg" height="384" width="512"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_2MB_ch9.wmv" expression="full" duration="838" fileSize="177138479" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_ch9.mp3" expression="full" duration="838" fileSize="6710275" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_ch9.mp4" expression="full" duration="838" fileSize="59021611" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_ch9.wma" expression="full" duration="838" fileSize="6788009" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_ch9.wmv" expression="full" duration="838" fileSize="37050459" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/4bf9/c1c12c83-1c76-45eb-8cc5-9e0f011f4bf9/BlendForDevelopers_ch9.wmv" length="37050459" type="video/x-ms-wmv"/>
      <dc:creator>Jeff Brand</dc:creator>
      <itunes:author>Jeff Brand</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/SlickThought/Three-Reasons-Developers-Should-Use-Expression-Blend/RSS</wfw:commentRss>
      <category>Blend</category>
      <category>Silverlight</category>
      <category>WP7</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Window Phone 7 Developer Tools + controls!</title>
      <description><![CDATA[
<p>Today the Windows Phone team released the final bits for Windows Phone 7!&nbsp; The tooling is free and will integrate with Visual Studio 2010 and Expression Blend 4 if you have them installed as well.&nbsp; Head over to
<a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce" title="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce">
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce</a> to get the RTM tooling.</p>
<p>Here is also a little list I’ve been keeping with useful controls around the internet!</p>
<table cellpadding="2" cellspacing="0" border="0">
<tbody>
<tr>
<td width="250" valign="top">
<h2>Controls</h2>
</td>
<td width="250" valign="top">
<h2>Random Resources</h2>
</td>
</tr>
<tr>
<td width="250" valign="top">
<p><strong>Silverlight Tool kit <br>
GestureService/GestureListener <br>
ContextMenu <br>
DatePicker <br>
TimePicker <br>
ToggleSwitch <br>
WrapPanel <br>
</strong><a href="http://bit.ly/aBZWSQ">http://bit.ly/aBZWSQ</a> </p>
<p><strong>Wheel Control</strong> <br>
<a href="http://bit.ly/bDcyFL">http://bit.ly/bDcyFL</a> </p>
<p><strong>Swipe Title</strong> <br>
<a href="http://bit.ly/balUu1">http://bit.ly/balUu1</a> </p>
<p><strong>Picker (Combo box) <br>
</strong><a href="http://bit.ly/coyJ1F">http://bit.ly/coyJ1F</a> </p>
<p><strong>Progress Bar <br>
</strong><a href="http://bit.ly/aAWd4K">http://bit.ly/aAWd4K<strong> </strong></a></p>
<p><strong>More Complex splash screen</strong> <br>
<a href="http://bit.ly/bGH93w">http://bit.ly/bGH93w</a> </p>
<p><strong>Touch tilting</strong> <br>
<a href="http://bit.ly/bptbs9">http://bit.ly/bptbs9</a> </p>
<p><strong>Clearable Textbox <br>
</strong><a href="http://bit.ly/csSidM">http://bit.ly/csSidM</a> </p>
<p><strong>Image Caching</strong> <br>
<a href="http://bit.ly/cktA7N">http://bit.ly/cktA7N</a></p>
</td>
<td width="250" valign="top">
<p><strong>Great list of resources <br>
</strong><a href="http://bit.ly/bVvIRn">http://bit.ly/bVvIRn</a> </p>
<p><strong>Detect if a listbox is done scrolling</strong> <br>
<a href="http://bit.ly/b1WfPO">http://bit.ly/b1WfPO</a> </p>
<p><strong>Pass data between pages <br>
</strong><a href="http://bit.ly/akIzLO">http://bit.ly/akIzLO</a> </p>
<p><strong>relative date time converter</strong> <br>
<a href="http://bit.ly/9F0gzP">http://bit.ly/9F0gzP</a> </p>
<p>Phone Styles <br>
accent color would be Style=&quot;{StaticResource PhoneAccentBrush}&quot; <br>
<a href="http://bit.ly/cUmhGi">http://bit.ly/cUmhGi</a></p>
</td>
</tr>
</tbody>
</table>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ff5ae0ea67b341fda7e29e7600c887e0">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/blog/Window-Phone-7-Developer-Tools--controls</comments>
      <itunes:summary>
Today the Windows Phone team released the final bits for Windows Phone 7!&amp;nbsp; The tooling is free and will integrate with Visual Studio 2010 and Expression Blend 4 if you have them installed as well.&amp;nbsp; Head over to

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce to get the RTM tooling.
Here is also a little list I’ve been keeping with useful controls around the internet!




Controls


Random Resources




Silverlight Tool kit 
GestureService/GestureListener 
ContextMenu 
DatePicker 
TimePicker 
ToggleSwitch 
WrapPanel 
http://bit.ly/aBZWSQ 
Wheel Control 
http://bit.ly/bDcyFL 
Swipe Title 
http://bit.ly/balUu1 
Picker (Combo box) 
http://bit.ly/coyJ1F 
Progress Bar 
http://bit.ly/aAWd4K 
More Complex splash screen 
http://bit.ly/bGH93w 
Touch tilting 
http://bit.ly/bptbs9 
Clearable Textbox 
http://bit.ly/csSidM 
Image Caching 
http://bit.ly/cktA7N


Great list of resources 
http://bit.ly/bVvIRn 
Detect if a listbox is done scrolling 
http://bit.ly/b1WfPO 
Pass data between pages 
http://bit.ly/akIzLO 
relative date time converter 
http://bit.ly/9F0gzP 
Phone Styles 
accent color would be Style=&amp;quot;{StaticResource PhoneAccentBrush}&amp;quot; 
http://bit.ly/cUmhGi




</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/blog/Window-Phone-7-Developer-Tools--controls</link>
      <pubDate>Thu, 16 Sep 2010 14:13:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/Window-Phone-7-Developer-Tools--controls</guid>      
      <dc:creator>Clint Rutkas</dc:creator>
      <itunes:author>Clint Rutkas</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/blog/Window-Phone-7-Developer-Tools--controls/RSS</wfw:commentRss>
      <category>Silverlight</category>
      <category>User Controls</category>
      <category>XAML</category>
      <category>XNA</category>
    </item>
  <item>
      <title>PicFx – Windows Phone Picture Effects Application – Part 1</title>
      <description><![CDATA[ <p>At the <a href="http://live.visitmix.com">MIX 2010 conference</a>, Microsoft announced its new mobile strategy with the <a href="http://developer.windowsphone.com">Windows Phone 7 platform</a>. Windows Phone 7 is a completely new mobile OS, and the best part is that Silverlight is THE technology for Windows Phone 7 application development. Apps are written with a special version of Silverlight based on Silverlight 3 plus some additions. Games with 3D hardware acceleration can be made with the <a href="http://en.wikipedia.org/wiki/Microsoft_XNA#XNA_Game_Studio_4">XNA Game Studio 4</a></p><p>Most of the <a href="http://blogs.msdn.com/b/gduthie/archive/2010/07/19/a-trio-of-windows-phone-7-previews.aspx">first technical previews</a> have stated that the Windows Phone has a pretty impressive photo application, and we can surely expect some pretty good cameras from the different phone hardware vendors. A Windows Phone 7 is required to have at least a 5 Megapixel camera. Another cool feature requirement of the Windows Phone camera system is called “pocket to picture.” This represents a special hardware button that launches the camera app even if the phone is locked. This feature will be great for capturing all those spontaneous moments in life. How often have you missed such snapshots because you were fumbling to unlock your phone and starting the camera app? I know this has happened to me quite often. </p><p>The ability to so quickly take pictures will result in some very cool photos. The original pictures might already look nice, but some will look even better if they are enhanced with a nice image effect. It's in this manner that this article and the PicFx application come into play. </p><p>This is the first article in a short series describing how to write picture effects applications for Windows Phone. The first article will show how to create the base Windows Phone application and how to implement some basic effects. <em>Spoiler: The next part will demonstrate how to write some more advanced effects you probably don't want to miss.</em></p><h3>The App in Action</h3><p>The video below demonstrates the application's features and also shows how the application can be used. It was recorded with the application running in the emulator.</p><h2>How it works</h2><p>The following sections will describe how this picture effects application was made. We will drill down from the User Interface (UI) Crust through the UI Mantle until we finally reach the Effects Core. Cross your fingers so a leak doesn't stop us.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb.png" border="0" alt="image" width="220" height="234"></a></p><h3>The User Interface</h3><p>We start our journey on the surface of the application.</p><p>The app uses the so-called Pivot control as the main UI template (Figure 1). Along with the Panorama control, the Pivot control is the dominating UI template used in standard Windows Phone applications / hubs. Both controls usually contain multiple items or views that can be navigated with a flick gesture. You can read more about these controls and the general design of Windows Phone applications in the official <a href="http://go.microsoft.com/fwlink/?LinkID=183218">Windows Phone UI Design and Interaction Guide</a>. </p><p>Since the official Silverlight version of the Pivot and Panorama controls haven't been released yet, we'll use this nice <a href="http://phone.codeplex.com">open source implementation from CodePlex</a> by <a href="http://blogs.msdn.com/members/Stephane-Crozatier/">Stephane Crozatier</a>.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_3.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_3.png" border="0" alt="image" width="463" height="480"></a></p><p><strong>Figure 1: The PicFx application layout using the Pivot control</strong></p><p>The relevant part from the MainPage.xaml:<strong>&nbsp;</strong></p><p><strong>XAML</strong><br><pre class="brush: xml">&lt;phoneCtrls:PivotControl Name=&quot;PivotCtrl&quot; &gt;

    &lt;phoneCtrls:PivotItem 
            Name=&quot;PivotItemPic&quot; 
            Title=&quot;PicFx&quot; 
            Header=&quot;Picture &quot; &gt;
        &lt;Image Name=&quot;Viewport&quot; /&gt;
    &lt;/phoneCtrls:PivotItem&gt;

    &lt;phoneCtrls:PivotItem  
            Name=&quot;PivotItemFx&quot; 
            Title=&quot; &quot; 
            Header=&quot;Effects &quot; &gt;
        &lt;phoneCtrls:PivotItem.Resources&gt;
            &lt;vm:EffectItems x:Key=&quot;effects&quot;/&gt;
        &lt;/phoneCtrls:PivotItem.Resources&gt;
        &lt;ListBox Name=&quot;ListBoxEffects&quot; 
                        SelectionMode=&quot;Single&quot; 
                        ItemsSource=&quot;{StaticResource effects}&quot; 
                        SelectionChanged=&quot;ListBox_SelectionChanged&quot; &gt;
            &lt;ListBox.ItemsPanel&gt;
                &lt;ItemsPanelTemplate&gt;
                    &lt;controlsToolkit:WrapPanel Width=&quot;480&quot; /&gt;
                &lt;/ItemsPanelTemplate&gt;
            &lt;/ListBox.ItemsPanel&gt;
            &lt;ListBox.ItemTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;StackPanel Orientation=&quot;Vertical&quot; Margin=&quot;14&quot; &gt;
                        &lt;Image Width=&quot;128&quot;
                                    Height=&quot;128&quot; 
                                    Source=&quot;{Binding Thumbnail}&quot; /&gt;
                        &lt;TextBlock Text=&quot;{Binding Name}&quot; 
                                   FontSize=&quot;{StaticResource PhoneFontSizeNormal}&quot; 
                                   VerticalAlignment=&quot;Center&quot; 
                                   HorizontalAlignment=&quot;Center&quot; /&gt;
                    &lt;/StackPanel&gt;
                &lt;/DataTemplate&gt;
            &lt;/ListBox.ItemTemplate&gt;
        &lt;/ListBox&gt;
    &lt;/phoneCtrls:PivotItem&gt;
&lt;/phoneCtrls:PivotControl&gt;</pre></p><p>The first Pivot item contains only the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image(VS.95).aspx">Image</a> showing the selected picture. The second view contains a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox(VS.95).aspx">ListBox control</a> with the thumbnails of the effects (see Figure 1). The list is data-bound to the StaticResource “effects,” an instance of the EffectItems class that is derived from ObservableCollection&lt;EffectItem&gt; and consists of EffectItem elements:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">public class EffectItems : ObservableCollection&lt;EffectItem&gt;
{
   public EffectItems()
   {
      Add(new EffectItem(new BlackWhiteEffect(), &quot;data/icons/BlackWhite.png&quot;));
      Add(new EffectItem(new SepiaEffect(), &quot;data/icons/Sepia.png&quot;));
   }
}

public class EffectItem
{
   public IEffect Effect { get; private set; }
   public string Name { get; private set; }
   public ImageSource Thumbnail { get; set; }

   public EffectItem(IEffect effect)
   {
      Effect = effect;
      Name = effect.Name;
   }

   public EffectItem(IEffect effect, string thumbnailRelativeResourcePath)
      : this(effect)
   {
      // Load the thumbnail from the resource stream 
      // using the WriteableBitmapEx lib
      Thumbnail = new WriteableBitmap(0, 0).
            FromResource(thumbnailRelativeResourcePath);
   }
 }</pre></p><p>The <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate(v=VS.95).aspx">ListBox.ItemTemplate</a> defines the visual representation of the data (EffectItem). The Image is data-bound to the Thumbnail property and the TextBlock is data-bound to the Name property of the EffectItem. The two controls are stacked together. Each Thumbnail has a size of 128 x 128 pixels and a Margin of 14 is used between the items so they get evenly spaced. Please also note the use of a StaticResource “PhoneFontSizeNormal” rather than a fixed FontSize. You can find all the predefined styles in the file %ProgramFiles%\SDKs\Windows Phone\v7.0\Design\ThemeResources.xaml. These styles, margins, and sizes are important because the Windows Phone is a multi-touch device that supports various themes. The <a href="http://go.microsoft.com/fwlink/?LinkID=183218">Windows Phone UI Design and Interaction Guide</a> provides more information about this topic.</p><p>The small thumbnail image is compiled into the assembly's resources. The <a href="http://writeablebitmapex.codeplex.com">WriteableBitmapEx</a>' FromResource extension method is then used to load the actual image data at runtime. The FromResource method takes the relative path of the image and automatically builds the <a href="http://msdn.microsoft.com/en-us/library/aa970069.aspx">Pack URI</a> that is needed to load data from the assembly's resources. Please note that it's recommended to add larger images as “Content” and not as “Resource” to keep the assembly file small.</p><p>The <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemspanel(v=VS.95).aspx">ListBox.ItemsPanel</a> specifies the layout of the items. A WrapPanel is used here so the items are stacked horizontally and wrapped when the panel limit is reached. The ItemsPanelTemplate specifies a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.stackpanel(v=VS.95).aspx">StackPanel</a> as default, which wastes precious space here. The WrapPanel originally comes from the <a href="http://silverlight.codeplex.com/">Silverlight Toolkit</a> and was <a href="http://www.designersilverlight.com/2010/06/28/using-wrappanel-and-dockpanel-in-windows-phone-7-with-blend/">ripped by Matthias Shapiro</a> and compiled for the Windows Phone 7.</p><h5>The Application Bar</h5><p>The Windows Phone <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.applicationbar(VS.92).aspx%5e">Application Bar</a> is a very useful system control that can contain up to four icon buttons and a set of text menu items. It's normally used as a toolbar to provide quickly accessible functionality. The Application Bar is easy to use and very handy for Windows Phone app development.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_4.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_4.png" border="0" alt="image" width="240" height="145"></a><strong><br>Figure 2: The Application Bar from the PicFx app</strong></p><p>The relevant part from the MainPage.xaml :<strong> </strong><strong>&nbsp;</strong></p><p><strong>XAML</strong><br><pre class="brush: xml">&lt;phone:PhoneApplicationPage.ApplicationBar&gt;
    &lt;shell:ApplicationBar IsVisible=&quot;True&quot;&gt;
        &lt;shell:ApplicationBarIconButton 
                Text=&quot;Choose&quot; 
                IconUri=&quot;/data/appbar/appbar.folder.rest.png&quot; 
                Click=&quot;ApplicationBarIconFolderButton_Click&quot;/&gt;
        &lt;shell:ApplicationBarIconButton 
                Text=&quot;Take&quot; 
                IconUri=&quot;/data/appbar/appbar.feature.camera.rest.png&quot; 
                Click=&quot;ApplicationBarIconCameraButton_Click&quot;/&gt;
        &lt;shell:ApplicationBarIconButton 
                Text=&quot;Save&quot; 
                IconUri=&quot;/data/appbar/appbar.save.rest.png&quot; 
                Click=&quot;ApplicationBarIconSaveButton_Click&quot;/&gt;
    &lt;/shell:ApplicationBar&gt;
&lt;/phone:PhoneApplicationPage.ApplicationBar&gt;</pre></p><p>The MainPage is derived from the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.controls.phoneapplicationpage(VS.92).aspx">PhoneApplicationPage</a> class, which defines the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.applicationbar(VS.92).aspx%5e">ApplicationBar</a> property. Three <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.applicationbariconbutton(VS.92).aspx">ApplicationBarIconButtons</a> are added here. Each one needs to have set a Text and an Icon. Microsoft provides a <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=369B20F7-9D30-4CFF-8A1B-F80901B2DA93&amp;displaylang=en">set of common application bar icons</a> that are used in the PicFx app. The set contains 32 dark and 32 light icons along with the corresponding vector versions.</p><h2>The Code Behind</h2><p>The UI is properly set up, the user is able to select an effect and click on the Application Bar buttons, but nothing will actually happen. Now it's time to breathe life into the UI elements.</p><h5><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_5.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_5.png" border="0" alt="image" width="228" height="234"></a></h5><h3>Choosing a Picture</h3><p>First of all we need to get a picture. One way to do this is to call the Windows Phone picture hub from our app and let the user select an image from the library. Fortunately, this task is pretty easy when using the Windows Phone <a href="http://msdn.microsoft.com/en-us/library/ff769556(v=VS.92).aspx">Task API</a>:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void Initialize()
{
   // ...
   // Init tasks
   photoChooserTask = new PhotoChooserTask();
   photoChooserTask.Completed &#43;= 
      PhotoProviderTaskCompleted;
   // ...
}</pre></p><p>A member variable of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.photochoosertask(v=VS.92).aspx">PhotoChooserTask</a> is instantiated in the Initialize method and an event handler for the <a href="http://msdn.microsoft.com/en-us/library/ff707989(v=VS.92).aspx">Completed</a> event is attached. The Initialize method is called in the <a href="http://msdn.microsoft.com/en-us/library/ms596558(vs.95)">Loaded</a> event handler of the page:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void PhotoProviderTaskCompleted
   (object sender, PhotoResult e)
{
   // Load the photo from the task result
   if (e != null &amp;&amp; e.TaskResult == TaskResult.OK)
   {
      var bmpi = new BitmapImage();
      bmpi.SetSource(e.ChosenPhoto);
      original = new WriteableBitmap(bmpi);
   }
}</pre></p><p>The Chooser's <a href="http://msdn.microsoft.com/en-us/library/ff707989(v=VS.92).aspx">Completed</a> event provides a <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.photoresult(v=VS.92).aspx">PhotoResult</a> that contains the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.taskeventargs.taskresult(v=VS.92).aspx">TaskResult</a>, the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.photoresult.chosenphoto(v=VS.92).aspx">ChosenPhoto</a> as a <a href="http://msdn.microsoft.com/en-us/library/8f86tw9e(vs.95)">Stream</a>, and some other properties. If the user hasn't cancelled the operation, the stream is used as the source of a BitmapImage, which is then assigned to a <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap%28VS.95%29.aspx">WriteableBitmap</a> member variable. </p><p>To launch the picture application, the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.photochoosertask.show(v=VS.92).aspx">PhotoChooserTask.Show</a> method is called when the corresponding Application Bar button is clicked:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void ApplicationBarIconFolderButton_Click
   (object sender, EventArgs e)
{
   photoChooserTask.Show();
}</pre></p><p>The Show method launches the Windows Phone picture hub. The current version of the Windows Phone operating system allows only one application to run at the same time, and our app is therefore terminated when the Chooser is started. Here's where the concept of <a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/07/15/understanding-the-windows-phone-application-execution-model-tombstoning-launcher-and-choosers-and-few-more-things-that-are-on-the-way-part-1.aspx">tombstoning</a> comes into play.</p><p>After the user selected an image or pressed the back button, the Chooser's <a href="http://msdn.microsoft.com/en-us/library/ff707989(v=VS.92).aspx">Completed</a> event is raised. You might have noticed the black screen that appears after the choose operation when you debug the application. As a result of the app termination, the Visual Studio debugging session is stopped. The Windows Phone 7 emulator detected that the app was started in a debug context and the emulator now waits at the black screen for re-attaching. So, just go back to Visual Studio and hit F5 (“Start Debugging”), then the debugger is reattached and the app continues. Of course, it's also possible to “Start Without Debugging” in Visual Studio.</p><h3>Taking a Picture</h3><p>Another way to get a picture into the app is to launch the camera application and let the user take an on-the-fly picture with the phone's camera:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void Initialize()
{
   // ...
   // Init tasks
   cameraCaptureTask = new CameraCaptureTask();
   cameraCaptureTask.Completed &#43;= 
      PhotoProviderTaskCompleted;
   // ...
}</pre></p><p>A member variable of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.cameracapturetask(v=VS.92).aspx">CameraCaptureTask</a> is also instantiated in the Initialize method and the same event handler used for the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.photochoosertask(v=VS.92).aspx">PhotoChooserTask</a> is attached. </p><p>To launch the camera application, the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.cameracapturetask.show(v=VS.92).aspx">CameraCaptureTask.Show</a> method is called when the corresponding Application Bar button is clicked:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp"></pre></p><p><strong>C# <br></strong></p><pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ApplicationBarIconCameraButton_Click<br>   (<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>   cameraCaptureTask.Show();<br>}</pre><p>&nbsp;</p><p>Obviously, the CameraCaptureTask API works the same way as the PhotoChooserTask.</p><p>The emulator doesn't support the camera application; therefore, the corresponding Application Bar button is disabled in the Initialize method when the app runs in the emulator:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">// Disable the camera button if the 
// app runs in the emulator
// The cast is needed since the 
// Buttons property is an IList of objects
var buttons = ApplicationBar.Buttons.Cast&lt;ApplicationBarIconButton&gt;();
var btn = buttons.Where(b =&gt;    
                  b.IconUri.ToString().
                     ToLower().Contains(&quot;camera&quot;)).FirstOrDefault();
if (btn != null)
{
   btn.IsEnabled = 
      (Microsoft.Devices.Environment.DeviceType != DeviceType.Emulator);
}</pre></p><p>In the current beta of the Windows Phone developer tools, the ApplicationBar has <a href="http://blogs.msdn.com/b/ptorr/archive/2010/06/18/why-are-the-applicationbar-objects-not-frameworkelements.aspx">some limitations</a> since it's rendered by the phone shell and is not at all a Silverlight element. This means that there's no Name property on the ApplicationBarIconButton, x:Name doesn't initialize the member variable, and data binding isn't possible. This is the reason for the above code, which uses the Buttons property and disables the button that has a camera icon if the app is executed in the emulator. As an alternative, the whole Application Bar can be set in the code-behind, including the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.applicationbariconbutton.isenabled(v=VS.92).aspx">IsEnabled</a> property, and a working member variable for the button can be initialized.</p><h5>Resizing a Picture</h5><p>Both Tasks return the full-sized image. These images can be large, depending on the phone's camera, and as a result the image processing can take quite a long time. Image processing is the operation where the actual effect is applied to an image. Until the picture is saved, however, only the Image control size is needed. That's why a resized version of the picture is used until saving. This speeds the interactive process up a lot:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">// From MaingPage.ResizeAndShowImage
// Fast and simple resize by using UIElement rendering
if (Viewport != null)
{
   Viewport.Source = bitmap;
   resized = new WriteableBitmap(Viewport, null);
}</pre></p><p>The WriteableBitmap resized member variable is being newly instantiated from the Viewport user control. This means that the Viewport image control is rendered at its actual size and the rendered pixels are used for the new and smaller WriteableBitmap instance where the effect gets applied.</p><h5>Applying an Effect</h5><p>When the user selects an effect item in the list, the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selectionchanged(v=VS.95).aspx">SelectionChanged</a> event is fired and the following event handler and methods are being called:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">// From the MainPage class
private void ListBox_SelectionChanged
   (object sender, SelectionChangedEventArgs e)
{
   if (resized != null)
   {
      // Apply selected effect and show image
      var result = ApplySelectedEffect(resized);
      ShowImage(result);
   }
}

private WriteableBitmap ApplySelectedEffect
   (WriteableBitmap bitmap)
{
   // Apply selected effect
   var result = bitmap;
   if (ListBoxEffects != null)
   {
      var item = ListBoxEffects.SelectedItem as EffectItem;
      if (item != null)
      {
         result = item.Effect.Process(bitmap);
      }
   }
   return result;
}

private void ShowImage(ImageSource result)
{
   // Show image and scroll to start page if needed
   if (Viewport != null)
   {
      Viewport.Source = result;
      if (PivotCtrl.SelectedIndex != 0)
      {
         PivotCtrl.ScrollPrev();
      }
   }
}</pre></p><p>The event handler calls the ApplySelectedEffect method with the resized bitmap as parameter. The ApplySelectedEffect method casts the SelectedItem to an EffectItem and then applies the underlying effect to the bitmap. Afterwards, the bitmap is set as source of the Viewport Image control in the ShowImage method. As the last step, the Pivot control's ScrollPrev method is called, the Pivot control is scrolled to the image view, and the user is presented with the applied effect.</p><h3>Removing an Effect</h3><p>If the user wants to remove the effect selection and see the original image again, he or she can hit the phone's hardware back button. This functionality is accomplished by attaching an event handler to the page's <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.backkeypress(VS.92).aspx">BackKeyPress</a> event:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void PhoneApplicationPage_BackKeyPress
   (object sender, CancelEventArgs e)
{
   if (ListBoxEffects != null &amp;&amp; 
      ListBoxEffects.SelectedItem != null)
   {
      ListBoxEffects.SelectedItem = null;
      e.Cancel = true;
   }
}</pre></p><p>The selected item of the ListBox is set to null which raises the SelectionChanged event (see above). The <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.canceleventargs.cancel(v=VS.95).aspx">Cancel</a></p><p>property of the event argument is set to true. Therefore, the app is not closed, which is the default functionality of the back key. The app will be closed if no effect was applied (ListBoxEffects.SelectedItem == null).</p><h3>Saving a Picture</h3><p>After the user applied an effect he probably wants to save the result back to the picture library / photo album. But there's nothing like a PhotoSaveTask available in the Silverlight SDK. Fortunately, the Windows Phone's XNA <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.medialibrary(XNAGameStudio.40).aspx">MediaLibrary</a> comes to the rescue. Only a reference to the Microsoft.Xna.Framework assembly is needed to use it in our Windows Phone Silverlight application. To make this task a bit easier, I wrote some reusable extension methods for the WriteableBitmap<strong>:</strong></p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">// From the file WriteableBitmapMediaLibraryExtensions.cs
// Saves the WriteableBitmap encoded as JPEG 
// to the Media library.
// The quality for JPEG encoding 
// has to be in the range 0-100, 
// where 100 is the best quality with the largest size.
public static void SaveToMediaLibrary
   (this WriteableBitmap bitmap, string name, int quality)
{
   using (var stream = new MemoryStream())
   {
      // Save the picture to the WP7 media library
      bitmap.SaveJpeg(
         stream, 
         bitmap.PixelWidth, 
         bitmap.PixelHeight, 
         0, 
         quality);
      stream.Seek(0, SeekOrigin.Begin);
      new MediaLibrary().SavePicture(name, stream);
   }
}</pre></p><p>The SaveToMediaLibrary method expects a name for the picture and the quality for JPEG encoding. The quality has to be in the range from 0 to 100, where 100 is the best image quality. Though a higher quality yields a larger file size, it's not recommended to use a quality below 70.</p><p>The MediaLibrary's <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.medialibrary.savepicture(v=XNAGameStudio.40).aspx">SavePicture</a> method expects a stream or a byte array as parameter containing an image encoded in the <a href="http://en.wikipedia.org/wiki/Jpeg">JPEG format</a>. Therefore, the WriteableBitmap is encoded as JPEG with the built-in <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.extensions.savejpeg(v=VS.92).aspx">SaveJpeg</a> extension method. The SaveJpeg method expects the targetStream, the width and height of the target, the orientation, which is not used at the moment, and the quality. The width and height parameters can be useful when a scaled version of the WriteableBitmap should be saved as JPEG.</p><p>The image will be saved when the disk floppy button in the ApplicationBar is clicked:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">private void ApplicationBarIconSaveButton_Click
   (object sender, EventArgs e)
{
   var result = ApplySelectedEffect(original);
   var name = String.Format(
      &quot;PicFx_{0:yyyy-MM-dd_hh-mm-ss-tt}.jpg&quot;, 
      DateTime.Now);
   result.SaveToMediaLibrary(name);
}</pre></p><p>The effect is applied to the original sized bitmap and a filename based on the current date and time is created. This filename is then passed to the SaveToMediaLibrary extension method, which will save the edited picture to the phone's media library / picture hub.</p><h2>The Effects</h2><p>Now that we have examined the UI crust and the underlying mantle, it's time to drill further into the core of our application—the image effects.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_6.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_6.png" border="0" alt="image" width="221" height="234"></a></p><p>The effects selectable by the end-user are made out of several base effects, which can be differently combined. Therefore, it's possible to make a wide range of different composite effects (outer core) using various combinations of base effects (inner core). This approach also guarantees high code reusability.</p><p>Regardless of whether the effect is a base effect or a composite effect, both implement the same IEffect interface (Figure 3). This interface is quite small. The Process method takes a <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap%28VS.95%29.aspx">WriteableBitmap</a> as parameter and returns a WriteableBitmap as result of the image processing.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_7.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_7.png" border="0" alt="image" width="307" height="168"></a></p><p><a name="_Ref267596083"><strong>&nbsp;</strong></a><strong>Figure 3: The IEffect interface</strong></p><h3>The Black &amp; White Effect</h3><p>This composite effect converts the input image to a grayscale image and slightly increases the contrast. The classic Black &amp; White effect is often used for portrait photos. Most pictures tend to look better when they're converted to an old school gray image. One might think that's the reason why I use this effect on my profile picture.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image30.png"><strong><img class="wlDisabledImage" title="image[30]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image30_thumb.png" border="0" alt="image[30]" width="261" height="480"></strong></a><strong><br>Figure 4: The Black &amp; White effect applied to the sample picture</strong></p><p>The Black &amp; White composite effect internally uses both the BrightnessContrast and Tint base effects (Figure 5). Therefore, it contains almost no code at all.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_8.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_8.png" border="0" alt="image" width="500" height="358"></a></p><p><a name="_Ref267598560"><strong>&nbsp;</strong></a><strong>Figure 5: The class diagram of the BlackWhiteEffect</strong></p><p>This is the complete code of the BlackWhiteEffect class without XML comments:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">public class BlackWhiteEffect : IEffect
{
   readonly TintEffect tintFx;
   readonly BrightnessContrastEffect contrastFx;

   public string Name { get { return &quot;Black &amp; White&quot;; } }

   public float ContrastFactor 
   {
      get { return contrastFx.ContrastFactor; }
      set { contrastFx.ContrastFactor = value; }
   }

   public BlackWhiteEffect()
   {
      tintFx = TintEffect.White;
      contrastFx = new BrightnessContrastEffect 
         { ContrastFactor = 0.15f };
   }

   public WriteableBitmap Process(WriteableBitmap input)
   {
      return contrastFx.Process(tintFx.Process(input));
   }
}</pre></p><h2>The Base Effects</h2><p>The Black &amp; White effect of the Outer Core doesn't have much code. So, where's all the code? Good question. Let's dig deeper into the Inner Core to see where the magic is happening.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_9.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_9.png" border="0" alt="image" width="221" height="234"></a></p><h3>The Tint Effect</h3><p>The Tint effect converts each pixel to gray and tints it with a parameterized color:</p><p><strong>&nbsp;</strong></p><p><strong>C#</strong><br><pre class="brush: csharp">public WriteableBitmap Process(WriteableBitmap input)
{         
   // Prepare some variables
   var result = new WriteableBitmap(
      input.PixelWidth, 
      input.PixelHeight);
   var resultPixels = result.Pixels;
   var inputPixels = input.Pixels;
   var ta = Color.A;
   var tr = Color.R;
   var tg = Color.G;
   var tb = Color.B;

   for (int i = 0; i &lt; inputPixels.Length; i&#43;&#43;)
   {
      // Extract color components
      var c = inputPixels[i];
      var a = (byte)(c &gt;&gt; 24);
      var r = (byte)(c &gt;&gt; 16);
      var g = (byte)(c &gt;&gt; 8);
      var b = (byte)(c);

      // Convert to gray with constant factors 
      // 0.2126, 0.7152, 0.0722
      int gray = (r *  6966 &#43; g * 23436 &#43; b *  2366) &gt;&gt; 15;

      // Apply Tint color
      a = (byte)((a    * ta) &gt;&gt; 8);
      r = (byte)((gray * tr) &gt;&gt; 8);
      g = (byte)((gray * tg) &gt;&gt; 8);
      b = (byte)((gray * tb) &gt;&gt; 8);

      // Set result color
      resultPixels[i] = (a &lt;&lt; 24) | 
         (r &lt;&lt; 16) | 
         (g &lt;&lt; 8) | 
         b;
   }

   return result;
}</pre></p><p>First, the result WriteableBitmap is initialized with the same size as the input image and the values of the <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.pixels(v=VS.95).aspx">Pixels</a> property are assigned to local variables. Using the local variables inside the processing loop is much faster than using the Pixels property, which means that a method is being called each time. The <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap%28VS.95%29.aspx">WriteableBitmap</a> uses the <a href="http://en.wikipedia.org/wiki/Rgb">RGB color space</a> to represent the pixels and is actually just a 32 bit integer array that stores the alpha, red, green, and blue (ARGB) byte components for all the pixels in a 1D array.</p><p>Inside the processing loop the red, green, and blue color components of each input pixel are extracted. Then, each component is multiplied with a constant factor and the elements are added to a scalar value. The result actually represents the <a href="http://en.wikipedia.org/wiki/Luminance_(relative)">luminance</a> of the pixel. The human eye is known to be more sensitive to green colors, which is the reason why the green component is weighted more. </p><p>The factors aren't applied as a floating-point multiplication; instead, the components are multiplied with large integer values in the range 2<sup>15</sup>. That's why the result is then divided by 32768 (2<sup>15</sup>) using a cheap bit shift operation. Integer operations are usually faster on most non-specialized CPUs, and on mobile CPUs. But this has to be proven in the future with a real Windows Phone device at hand. One thing is clear, the integer operations perform better than floating point operations in the emulator.</p><p>In the last processing step the actual tint Color property is applied by multiplying each component of the color with the gray value of the input pixel. Then the byte color components are combined into the result integer pixel. Again, only fast integer operations are used here.</p><p>The Black &amp; White effect uses white as tint color, which represents 255, 255, 255 as a byte in the common additive RGB system or 1f, 1f, 1f as a normalized floating point. This means the gray color is used directly and no tinting is actually applied.</p><h3>The Brightness and Contrast Modification Effect</h3><p>The second and last base effect from the Black &amp; White effect is the brightness and contrast modification. The Black &amp; White effect only increases the contrast, but the BrightnessContrastEffect can alter contrast and brightness in the same process since both modifications are commonly used together:<strong></strong></p><p><strong>C#</strong><br><pre class="brush: csharp">public WriteableBitmap Process(WriteableBitmap input)
{         
   // Prepare some variables
   var result = new WriteableBitmap(
      input.PixelWidth, 
      input.PixelHeight);
   var resultPixels = result.Pixels;
   var inputPixels = input.Pixels;
   // Convert to integer factors
   var bfi = (int)(BrightnessFactor * 255);
   var cf = (1f &#43; ContrastFactor) / 1f;
   cf *= cf;
   var cfi = (int)(cf * 32768);

   for (int i = 0; i &lt; inputPixels.Length; i&#43;&#43;)
   {
      // Extract color components
      var c = inputPixels[i];
      var a = (byte)(c &gt;&gt; 24);
      var r = (byte)(c &gt;&gt; 16);
      var g = (byte)(c &gt;&gt; 8);
      var b = (byte)(c);
            
      // Modify brightness (addition)
      if (bfi != 0)
      {
         // Add brightness
         int ri = r &#43; bfi;
         int gi = g &#43; bfi;
         int bi = b &#43; bfi;

         // Clamp to byte boundaries
         r = (byte)(ri &gt; 255 ? 255 : (ri &lt; 0 ? 0 : ri));
         g = (byte)(gi &gt; 255 ? 255 : (gi &lt; 0 ? 0 : gi));
         b = (byte)(bi &gt; 255 ? 255 : (bi &lt; 0 ? 0 : bi));
      }
 
      // Modify contrast (multiplication)
      if (cfi != 0)
      {
         // Transform to range [-128, 127]
         int ri = r - 128;
         int gi = g - 128;
         int bi = b - 128;

         // Multiply contrast factor
         ri = (ri * cfi) &gt;&gt; 15;
         gi = (gi * cfi) &gt;&gt; 15;
         bi = (bi * cfi) &gt;&gt; 15;

         // Transform back to range [0, 255]
         ri = ri &#43; 128;
         gi = gi &#43; 128;
         bi = bi &#43; 128;

         // Clamp to byte boundaries
         r = (byte)(ri &gt; 255 ? 255 : (ri &lt; 0 ? 0 : ri));
         g = (byte)(gi &gt; 255 ? 255 : (gi &lt; 0 ? 0 : gi));
         b = (byte)(bi &gt; 255 ? 255 : (bi &lt; 0 ? 0 : bi));
      }  

      // Set result color
      resultPixels[i] = (a &lt;&lt; 24) | 
         (r &lt;&lt; 16) | 
         (g &lt;&lt; 8) | 
         b;
   }

   return result;
}</pre></p><p>A with most of the effects, the result WriteableBitmap is first initialized with the same size as the input image and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.pixels(v=VS.95).aspx">Pixels</a> property is locally referenced. The range of the ContrastFactor and the BrightnessFactor floating point properties is normalized to [-1, 1], which makes the class easier to use. But floating operations are slower than integer operations; therefore, local, scaled integer variables are initialized for these properties, too. </p><h3>Brightness</h3><p>Inside the loop, the color components of each input pixel are again extracted. Then it's determined whether the Brightness should be modified. The <a href="http://en.wikipedia.org/wiki/Brightness">Brightness</a> modification is actually an addition or subtraction of the pixel's <a href="http://en.wikipedia.org/wiki/Luminance_(relative)">luminance</a>. In terms of vector arithmetic, it can be described as a translation. But I don't want to bore you with mathematical details and, as always, a picture is worth a thousand words:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_10.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_10.png" border="0" alt="image" width="500" height="330"></a><a name="_Ref267682354"><strong><br></strong></a><strong>Figure 6: The brightness transfer functions from left to right: 1:1, subraction, addition</strong></p><p>Figure 6 shows three different brightness <a href="http://en.wikipedia.org/wiki/Transfer_function">transfer functions</a> along with the picture resulting from when the function is applied to the sample image. The y-axis represents the input value and the x-axis represents the corresponding output value for the pixel's luminosity. The left image is the original. The function curve in the middle has a negative offset, which means that a subtraction is performed and the brightness gets decreased. The right curve has a positive offset which means that an addition is performed and the brightness gets increased. So the brightness modification is actually the <a href="http://en.wikipedia.org/wiki/Y-intercept">y-intercept</a> change of the linear luminance transfer function.</p><h3>Contrast</h3><p>On the other hand, the <a href="http://en.wikipedia.org/wiki/Contrast_(vision)">Contrast</a> modification is a multiplication of the pixel's luminance. It's a uniform scaling of the color vector (Figure 7). In the above code the value of the pixel components is transformed to the range [-128, 127] and then multiplied with the contrast factor. Due to the range transformation, darker pixels get darker and lighter pixels get lighter when the contrast is increased with a positive factor. Then the pixel is transformed back to the range [0, 255] and the boundaries of the color byte components are checked. The last processing step is the combination of the byte components into the result integer pixel. Again, everything was done with only fast integer operations.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_11.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_11.png" border="0" alt="image" width="500" height="329"></a><a name="_Ref267683821"><strong><br></strong></a><strong>Figure 7: The contrast transfer functions from left to right: 1:1, scale down, scale up</strong></p><p>The contrast transfer function in the middle of Figure 7 has a factor below 1, which means the slope is shallower and the contrast gets decreased. The right curve has a factor above 1, which means the slope is steeper and the contrast gets increased. The contrast modification is actually the <a href="http://en.wikipedia.org/wiki/Slope">slope</a> change of the linear luminance transfer function.</p><h3>The Sepia Effect</h3><p>After the boring details of the Inner Core effects, it's time to use these base effects in a different combination to make an interesting Outer Core effect.</p><p>The Sepia effect is another composite effect that tints the image and changes the contrast. Like the Black &amp; White, the <a href="http://en.wikipedia.org/wiki/Sepia_tone#Sepia_toning">Sepia</a> effect is also a very popular image effect to give a photo the old-touch. Sepia is some kind of a brown color tint.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_12.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_12.png" border="0" alt="image" width="261" height="480"></a></p><p><strong>Figure 8: The Sepia effect applied to the sample picture</strong></p><p>The Sepia effect is basically the same as the Black &amp; White effect, only with slightly other parameter values and a different tint color of course. Actually, only the contrast factor is a bit less than the Black &amp; White effect and the tint color is Sepia (230, 179, 77).</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_13.png"><strong><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_13.png" border="0" alt="image" width="500" height="358"></strong></a></p><p><strong>Figure 9: The class diagram of the SepiaEffect</strong></p><p>The code of the Sepia effect in its whole glory:<br><strong>C#</strong><br><pre class="brush: csharp">public class SepiaEffect : IEffect
{
   readonly TintEffect tintFx;
   readonly BrightnessContrastEffect contrastFx;

   public string Name { get { return &quot;Sepia&quot;; } }

   public float ContrastFactor 
   {
      get { return contrastFx.ContrastFactor; }
      set { contrastFx.ContrastFactor = value; }
   }

   public SepiaEffect()
   {
      tintFx = TintEffect.Sepia;
      contrastFx = new BrightnessContrastEffect 
         { ContrastFactor = 0.05f };
   }

   public WriteableBitmap Process(WriteableBitmap input)
   {
      return contrastFx.Process(tintFx.Process(input));
   }
}</pre></p><h2>Conclusion</h2><p>We drilled down from the UI Crust with the Pivot control template and the Windows Phone Application Bar through the UI Mantle with all the IO functionality. Then we drilled further into the Effects Core with the Black &amp; White and Sepia effects. Finally, we reached the Inner Core and learned how the BrightnessContrast and Tint base effects work. </p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_15.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_15.png" border="0" alt="image" width="220" height="234"></a></p><p>I hope you didn't get lost during our long journey because this here isn't the end. The second article of this series will describe how to implement advanced effects (the cool stuff) and many more.</p><h2>About The Author</h2><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_14.png"><img class="wlDisabledImage" title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10048007/image_thumb_14.png" border="0" alt="image" width="140" height="140" align="right"></a>René Schulte is a .Net / Silverlight developer and Microsoft <a href="http://mvp.support.microsoft.com/profile/Rene.Schulte">Silverlight MVP</a> passionate about real-time computer graphics, physics, AI, and algorithms. He loves C#, Shaders, Augmented Reality, and computer vision. He started the <a href="http://SLARToolkit.codeplex.com">SLARToolkit</a>, the <a href="http://WriteableBitmapEx.codeplex.com">WriteableBitmapEx</a>, and the <a href="http://Matrix3DEx.codeplex.com">Matrix3DEx</a> Silverlight open source projects, and he has a <a href="http://rene-schulte.info">Silverlight website</a> powered by real time soft body physics. He is also a regular author for Microsoft's Coding4Fun. Contact information can be found on his <a href="http://rene-schulte.info">Silverlight website</a>, his <a href="http://blog.rene-schulte.info">blog</a>, or via <a href="http://twitter.com/rschu">Twitter</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e2e65876b8f94e45b5d09e7600c8dd84">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-1</comments>
      <itunes:summary> At the MIX 2010 conference, Microsoft announced its new mobile strategy with the Windows Phone 7 platform. Windows Phone 7 is a completely new mobile OS, and the best part is that Silverlight is THE technology for Windows Phone 7 application development. Apps are written with a special version of Silverlight based on Silverlight 3 plus some additions. Games with 3D hardware acceleration can be made with the XNA Game Studio 4Most of the first technical previews have stated that the Windows Phone has a pretty impressive photo application, and we can surely expect some pretty good cameras from the different phone hardware vendors. A Windows Phone 7 is required to have at least a 5 Megapixel camera. Another cool feature requirement of the Windows Phone camera system is called “pocket to picture.” This represents a special hardware button that launches the camera app even if the phone is locked. This feature will be great for capturing all those spontaneous moments in life. How often have you missed such snapshots because you were fumbling to unlock your phone and starting the camera app? I know this has happened to me quite often. The ability to so quickly take pictures will result in some very cool photos. The original pictures might already look nice, but some will look even better if they are enhanced with a nice image effect. It&#39;s in this manner that this article and the PicFx application come into play. This is the first article in a short series describing how to write picture effects applications for Windows Phone. The first article will show how to create the base Windows Phone application and how to implement some basic effects. Spoiler: The next part will demonstrate how to write some more advanced effects you probably don&#39;t want to miss.The App in ActionThe video below demonstrates the application&#39;s features and also shows how the application can be used. It was recorded with the application running in the emulator.How it worksThe following sections will des</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-1</link>
      <pubDate>Mon, 09 Aug 2010 17:00:52 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-1</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10048007_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10048007_220.jpg" height="165" width="220"/>      
      <dc:creator>Rene Schulte</dc:creator>
      <itunes:author>Rene Schulte</itunes:author>
      <slash:comments>20</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/PicFx--Windows-Phone-Picture-Effects-Application--Part-1/RSS</wfw:commentRss>
      <category>Silverlight</category>
      <category>Windows Phone</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Creating a Shuffleboard Game using Silverlight</title>
      <description><![CDATA[<p>In this walkthrough, we will create a <a href="http://en.wikipedia.org/wiki/Table_shuffleboard">
table shuffleboard</a> style game for Windows Phone 7 using Silverlight. Many bars feature these long wooden table games, in which players slide metal pucks down the length of the table, attempting to get as close as possible to the far end without sliding
 off the edge.</p>

<h3><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/6378.image_5F00_28FB581F.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/2086.image_5F00_thumb_5F00_2F422EAD.png" width="223" height="435"></a>
 Multi-Targeting</h3>
<p>Windows Phone 7 uses a version of Silverlight 3 with a few bonus features. Because this version of Silverlight is so close to the Web version of Silverlight 3, we'll take the approach of
<i>Multitargeting</i> a solution for both platforms. To do so, start with a Silverlight 3 (web) application template, and then add in a Windows Phone project with linked files that re-use the Silverlight 3 solution. This allows us to deploy to many different
 platforms using the same code base.</p>
<p>Let's get started by creating our Solution in this way.</p>
<h3>Creating the Solution and MainPage</h3>
<ol>
<li>In Expression Blend 4, create a new Silverlight Application &#43; Website template named Shuffleboard. Be sure to select “3.0” from the Version dropdown, as this is what is supported by Windows Phone (in a little bit we'll add in the Windows Phone project template
 as well). <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/4721.image_5F00_740E52E1.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3731.image_5F00_thumb_5F00_2599C077.png" width="465" height="427"></a>
</li><li>In the Objects and Timeline Panel, select the main UserControl and set its Width to 480 and its Height to 800. This is the size of a Windows Phone UI in Portrait mode.
</li><li>Select the LayoutRoot Grid and set its Width to 480 and its Height to 800. </li><li>For games, a Canvas layout container is better than a Grid, so let's change the LayoutRoot container type. Right-click LayoutRoot and select Change Layout Type/Canvas.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0820.image_5F00_57252E0C.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8865.image_5F00_thumb_5F00_5DD8378F.png" width="299" height="304"></a>
</li><li>Since some parts of our UI can appear outside of the game area, we want to add a Clip to this main canvas so that the user does not see these outside elements. Add the following just under the LayoutRoot Canvas:
<br>
This XAML is snippet “<b>MainPage Clip</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Canvas.Clip</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">RectangleGeometry</span> <span class="attr">Rect</span><span class="kwrd">=&quot;0,0,480,800&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Canvas.Clip</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
 {font-size:small;
 color:black;
 font-family:consolas,"Courier New",courier,monospace;
 background-color:#ffffff}
.csharpcode 
 {margin:0em}
.csharpcode .rem
 {color:#008000}
.csharpcode .kwrd
 {color:#0000ff}
.csharpcode .str
 {color:#006080}
.csharpcode .op
 {color:#0000c0}
.csharpcode .preproc
 {color:#cc6633}
.csharpcode .asp
 {background-color:#ffff00}
.csharpcode .html
 {color:#800000}
.csharpcode .attr
 {color:#ff0000}
.csharpcode .alt
 {background-color:#f4f4f4;
 width:100%;
 margin:0em}
.csharpcode .lnum
 {color:#606060}
-->
</style></li><li>We'll be using some pre-built Behaviors that make it easy to introduce physics into Silverlight using the Farseer Physics Library. Right-click the Silverlight project and select Add Reference. Select the following assemblies, located in the sample download:
<br>
<br>
\ShuffleBoard\Bin\Debug\FarseerPhysics.dll <br>
\ShuffleBoard\Bin\Debug\Spritehand.FarseerHelper.dll <br>
\ShuffleBoard\Bin\Debug\Spritehand.PhysicsBehaviors.dll <br>
<br>
<strong>NOTE: </strong>To learn more about the Physics Helper Library, visit <a href="http://physicshelper.codeplex.com">
http://physicshelper.codeplex.com</a> </li></ol>
<p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/8/9/1/6/5/5/ShuffleboardPart1_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/8/9/1/6/5/5/ShuffleboardPart1_512_ch9.png, postid=556198" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p>
<h3>Creating the Game User Control</h3>
<p>Next we'll create a separate user control that will contain the core game logic. By creating a separate user control, we can easily target different platforms by placing the user control inside different MainPage elements.
</p>
<ol>
<li>Right-click the Shuffleboard Silverlight project and select Add New Item. Select UserControl and name the control “ucMainGame”.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0523.image_5F00_127893CB.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/7701.image_5F00_thumb_5F00_1616AEA8.png" width="299" height="324"></a>
</li><li>Change the LayoutRoot element from a Grid to a Canvas. </li><li>Set the Width to 480 and the Height to 800 for both the UserControl and LayoutRoot Canvas elements.
</li><li>Set the Background color to Black for the LayoutRoot Canvas. </li><li>Build the project by pressing Ctrl&#43;Shift&#43;B. </li><li>Back on MainPage, add an instance of ucMainGame to the page by going to the Assets Panel and expanding Controls/All. Drag an instance of ucMainGame to the artboard.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/1513.image_5F00_5C939EB0.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/6305.image_5F00_thumb_5F00_432B9B76.png" width="496" height="296"></a>
</li><li>Rename the ucMainGame control to ucMainGame1. </li><li>Set the Left and Top properties of ucMainGame1 to 0. </li></ol>
<h3>Creating the Table</h3>
<p>We'll use a pre-rendered PNG image for the shuffleboard table.</p>
<ol>
<li>Create a new subfolder in the Silverlight project named “images”. </li><li>Add the following JPG image into the new images subfolder, located in the sample download:
<br>
\ShuffleBoard\images\shuffleboardTable.jpg </li><li>Open the ucMainGame user control. </li><li>Insert a new Canvas element named cnvTable, and set the following attributes:
<ol>
<li>Width = 480 </li><li>Height = 800 </li><li>Left = 0 </li><li>Top = 0 </li></ol>
</li><li>In the Assets Panel, expand the Behaviors category and drag a PhysicsControllerBehavior on the cnvTable. This behavior introduces the core physics simulation into the game. Set the properties of the Physics Contoller as follows (this turns of gravity and
 sets some other physics parms): <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/1512.image_5F00_14D215C9.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/7701.image_5F00_thumb_5F00_49727204.png" width="333" height="293"></a>
</li><li>Inside the cnvTable Canvas, add a second Canvas named cnvTableInner, which will hold the table image. Set the following properties on cnvTableInner:
<ol>
<li>Width = 360 </li><li>Height = 1077 </li><li>Left = 60 </li><li>Top = -277 </li></ol>
</li><li>Drag the shuffleboardTable.jpg image from the Projects Panel into cnvTableInner. Set the following properties on the image:
<ol>
<li>Width = 360 </li><li>Height = 1077 </li><li>Left = 0 </li><li>Top = 0 </li></ol>
</li><li>The Objects and Timeline Panel should look like so: <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0042.image_5F00_223828CF.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8468.image_5F00_thumb_5F00_0144B628.png" width="278" height="221"></a>
</li><li>We will need to detect when a puck hits the edge of the table and “falls off.” Let's add in some Rectangle elements and add Physics Behaviors to them.
</li><li>Add a new Rectangle named rectSensorLeft and size it so that it covers the entire left side of the table. Set the following properties:<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0042.image_5F00_6EFBEF65.png"><img title="image" border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/7701.image_5F00_thumb_5F00_5FE5108B.png" width="122" height="240"></a>
<ol>
<li>Width = 60 </li><li>Height = 1190 </li><li>Left = -40 </li><li>Top = -334 </li><li>Opacity = 20% </li></ol>
</li><li>Drag a PhysicsObjectBehavior from the Assets Panel Behaviors onto rectSensorLeft, and then set its IsStatic property to true.
</li><li>Add three more Rectangles by copying rectSensorLeft, so that they surround the borders of the table:
<ol>
<li>rectSensorRight </li><li>rectSensorTop </li><li>rectSensorBottom </li></ol>
</li><li>Your artboard should look similar to the following: <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8054.image_5F00_467D0D51.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/2110.image_5F00_thumb_5F00_4C57B0EA.png" width="195" height="412"></a>
</li><li>Now we'll add in the goal Rectangles at the end of the table. These will be used to determine the number of points a puck receives. Draw out three Rectangles that cover the width of the board and are 100 pixels high. Name these rectPoints3, rectPoints2,
 and rectPoints1. Set their Stroke to Red and their Fill to No brush. </li><li>Add a TextBlock element inside each Rectangle to depict the points. Set the text properties to 3, 2, and 1 so that the artboard looks similar to the following:
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/7416.image_5F00_647B1B45.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3603.image_5F00_thumb_5F00_099865B2.png" width="430" height="353"></a>
</li><li>We'll also need a Rectangle representing the “slide zone” where players can legally slide a puck (we don't want to allow sliding all of the way down the table!). Add a Rectangle named rectInBounds and position it at the lower end of the table:
<ol>
<li>Width=360 </li><li>Height=292 </li><li>Left = 60 </li><li>Top = 508 </li><li>Fill = No Brush </li><li>Stroke = Red </li></ol>
</li></ol>
<p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/9/9/1/6/5/5/ShuffleboardPart2_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/9/9/1/6/5/5/ShuffleboardPart2_512_ch9.png, postid=556199" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p>
<h3>Adding the Pucks</h3>
<p>For the pucks, we are going to add in an existing control which has the artwork completed.
</p>
<ol>
<li>Right-click the project and select Add Existing Item. </li><li>Browse to the following two files in the sample code download: <br>
\ShuffleBoard\ucPuck.xaml <br>
\ShuffleBoard\ucPuck.xaml.cs </li><li>Open ucPuck.xaml on the artboard and notice the following in the Objects and Timeline Panel:
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/4572.image_5F00_286ED990.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8308.image_5F00_thumb_5F00_1A3060A0.png" width="494" height="179"></a>
<ol>
<li>There is a Canvas named Puck that has a PhysicsObjectBehavior applied to it. This allows each instance of this Canvas to behave like a Physics Object so it animates with velocity and force and participates in collisions. Note that this Behavior has a large
 MomentOfInertia value. This keeps the object from rotating due to torque and collisions. Also note the RestitutionCoefficient, which gives the object some “bounce.”
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/6330.image_5F00_67CC8D20.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3108.image_5F00_thumb_5F00_7289E475.png" width="328" height="198"></a>
</li><li>There is a “cnvInner” Canvas that defines the look of the Puck. </li><li>There is a StoryBoard defined, sbLostPuck, which we will execute when the puck “falls off the edge” of the table.
</li><li>Open the code-behind file, ucPuck.xaml.cs, and note the get / set property for the color of the puck. This will allow us to create both Red and Blue pucks for each player.
</li></ol>
</li><li>Build the project by hitting Ctrl&#43;Shift&#43;F5 and go back to ucMainGame. </li><li>From the Assets Panel, expand Controls/All and find the ucPuck control. Drag an instance of this onto the artboard. Name this
<b>bluePuck1</b>. </li><li>Copy and paste bluePuck1 twice so that you have three blue pucks. Name the new pucks
<b>bluePuck2</b> and <b>bluePuck3</b>. </li><li>Copy and paste a fourth puck and name it <b>redPuck1</b>. In the Properties Panel, go to the Miscellaneous Category and change the ColorHighlight and ColorMain properties to a Red color:
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/5340.image_5F00_4B4F9B40.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/2438.image_5F00_thumb_5F00_66F42736.png" width="334" height="217"></a>
</li><li>Copy and Paste <b>redPuck1</b> two times and rename these new pucks <b>redPuck2</b> and
<b>redPuck3</b>. </li><li>Let's test our table. Find the PhysicsControllerBehavior just under the cnvTable Canvas in the Objects and Timeline Panel and set the MousePickEnabled property to true.
</li><li>Run the project by clicking F5. Try dragging some pucks around with the mouse.
</li></ol>
<p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/1/0/2/6/5/5/ShuffleboardPart3_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/1/0/2/6/5/5/ShuffleboardPart3_512_ch9.png, postid=556201" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p><h3>Adding the Scoreboard</h3>
<p>We need a way of tracking players' scores, so let's add in a simple scoreboard for Blue vs. Red.</p>
<ol>
<li>Right-click the project and select Add Existing Item. </li><li>Browse to the following two files in the download: <br>
\ShuffleBoard\ShuffleBoard\ucScoreBoard.xaml <br>
\ShuffleBoard\ShuffleBoard\ucScoreBoard.xaml.cs </li><li>Open ucScoreBoard and notice the following:
<ol>
<li>It has a TextBlock for Red scores and a TextBlock for Blue scores. </li><li>In the code-behind, there are setters and getters to set the score. </li></ol>
</li><li>Build the project by selecting Ctrl&#43;Shift&#43;B. </li><li>Switch back to ucMainGame. </li><li>Drag an instance of ucScoreBoard from the Assets Panel onto into LayoutRoot. </li><li>Name the element <b>ucScoreBoard1</b>, and position it at the top left of the Canvas like so:
</li></ol>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3286.image_5F00_2AC85B8E.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8080.image_5F00_thumb_5F00_257974DD.png" width="227" height="373"></a>
</p>
<h3>Adding a Player Up Display</h3>
<p>We'll need a simple control that displays which player's turn it is. </p>
<ol>
<li>Right-click the Silverlight project and select Add/Existing Item. </li><li>Browse to and select the following two files in the sample folder: <br>
\ShuffleBoard\ucPlayerUp.xaml <br>
\ShuffleBoard\ucPlayerUp.xaml.cs </li><li>Note the following about ucPlayerUp:
<ol>
<li>The code-behind file has a simple property, IsBlueTurn, which shows the appropriate message in the UI.
</li></ol>
</li><li>Build the project by clicking Ctrl&#43;Shift&#43;B </li><li>Back on ucMainGame, drag an instance of ucPlayerUp into cnvTableInner. </li><li>Name the control <b>ucPlayerUp1</b> , and set the following properties: <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/5661.image_5F00_4F797305.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/5672.image_5F00_thumb_5F00_43E3B5C6.png" width="296" height="229"></a>
</li></ol>
<h3>Adding a 3D Look</h3>
<p>Let's give our table a bit of a 3D look by adding a Perspective transform so the table appears to go off into the distance.
</p>
<ol>
<li>Create a new StoryBoard named sbRotateTable. <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/2541.image_5F00_4781D0A3.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/2134.image_5F00_thumb_5F00_4E34DA26.png" width="388" height="151"></a>
</li><li>Select the cnvTable Canvas element. </li><li>Advance the timeline ahead one second. </li><li>In the Properties Panel, under Projection, set the X value to -40. <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0871.image_5F00_54E7E3A9.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/1464.image_5F00_thumb_5F00_46A96AB9.png" width="327" height="138"></a>
</li><li>Your artboard should now look something like this: <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8802.image_5F00_3460A3F7.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3531.image_5F00_thumb_5F00_01909D83.png" width="352" height="428"></a>
</li><li>Close the Storyboard to end recording. <br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/3124.image_5F00_59EA2158.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0003.image_5F00_thumb_5F00_04C2856B.png" width="300" height="129"></a>
</li><li>We want to rotate the table after the PhysicsController is initialized so the Physics Helper can determine the boundaries of the physics objects properly. Start by adding in some Using statements at the top of ucMainGame.xaml.cs:
<br>
This code is snippet “<b>ucMainGame Imports</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> Spritehand.FarseerHelper;
<span class="kwrd">using</span> FarseerGames.FarseerPhysics.Mathematics;
<span class="kwrd">using</span> System.ComponentModel;</pre>
</li><li>Next, let's add in some class-level declarations, which will store the physics controller, list of pucks, and some variables used to track shooting and scoring:
<br>
This code is snippet “<b>ucMainGame Declarations</b>” inside snippets.txt.
<pre class="csharpcode">PhysicsControllerMain _physicsController;
List&lt;PhysicsSprite&gt; _pucks = <span class="kwrd">new</span> List&lt;PhysicsSprite&gt;();
List&lt;PhysicsSprite&gt; _redPucks = <span class="kwrd">new</span> List&lt;PhysicsSprite&gt;();
Point _ptStartShot;
<span class="kwrd">bool</span> _draggingPuck;
<span class="kwrd">int</span> _draggingStartTick;

<span class="kwrd">int</span> _currentPuckToShoot = 0;
<span class="kwrd">int</span> _currentPuckShot = -1;
<span class="kwrd">int</span> _gameOverScore = 15;</pre>
</li><li>In the ucMainGame() constructor, add some code to set the MaxFrameRate to 30 (Windows Phone will be limited to 30 FPS) and wire up the Loaded event handler.
<br>
This code is snippet “<b>ucMainGame Constructor</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">this</span>.Loaded &#43;= <span class="kwrd">new</span> RoutedEventHandler(ucMainGame_Loaded);
Application.Current.Host.Settings.MaxFrameRate = 30;</pre>
</li><li>Implement the ucMainGame_Loaded event handler, which gets a reference to the Physics Controller and wires up our event handlers.
<br>
This code is snippet “<b>ucMainGame Loaded</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">void</span> ucMainGame_Loaded(<span class="kwrd">object</span> sender, RoutedEventArgs e)
{
    <span class="kwrd">if</span> (DesignerProperties.GetIsInDesignMode(<span class="kwrd">this</span>))
        <span class="kwrd">return</span>;

    _physicsController = 
        cnvTable.GetValue(
            PhysicsControllerMain.PhysicsControllerProperty
        ) <span class="kwrd">as</span> PhysicsControllerMain;
    _physicsController.Initialized &#43;= _physicsController_Initialized;
    _physicsController.Collision &#43;= _physicsController_Collision;
    _physicsController.TimerLoop &#43;= _physicsController_TimerLoop;
}</pre>
</li><li>Next, we'll add in the event handlers that we just wired up in the loaded event. Note that the Initialized event starts the Rotate Table StoryBoard.
<br>
This code is “<b>ucMainGame Event Handlers</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">void</span> _physicsController_Initialized(<span class="kwrd">object</span> source)
{
    sbRotateTable.Begin();
}

<span class="kwrd">void</span> _physicsController_Collision(<span class="kwrd">string</span> sprite1, <span class="kwrd">string</span> sprite2)
{ }

<span class="kwrd">void</span> _physicsController_TimerLoop(<span class="kwrd">object</span> source)
{ }</pre>
</li><li>Run the Project by clicking F5. Note the 3D look and try manipulating the pucks with the mouse.
</li></ol>
<h3>Controlling the Pucks</h3>
<p>Next, we'll add logic to control the player's turn and control and along with score. Note that, when we implement the Windows Phone version in a bit, we can take advantage of Multitouch Manipulation events. But since these events are not available in the
 Web version of Silverlight 3, we'll use a simple mouse input mechanism.</p>
<ol>
<li>Let's turn off the default mouse manipulation. Select the PhysicsControllerBehavior just under the cnvTable Canvas and set the MousePickEnabled property to false.
</li><li>We need to get references to our Pucks, which the Physics Helper has translated into PhysicsSprite objects. A Physics Sprite contains the XAML UI for the Physics Object, plus the Physics Engine attributes for the underlying physics objects–including boundary
 shape, mass, velocity, etc. <br>
This code is “<b>ucMainGame Initialized</b>” inside snippets.txt. </li><li>Now we need to handle the Mouse events on the pucks in order to control the player's shot. When the player clicks the mouse down on a puck, we track the position along with time that they clicked. When the player moves the mouse, we update the puck position
 and also check if the player paused or moved backwards. We do this in case the player is just adjusting the puck position and not yet sliding the puck for a shot. Finally, in the Mouse up event, we release the puck in the specified direction and apply an appropriate
 amount of force to it.&nbsp; Copy in the snippet “<b>Puck Mouse Control</b>” from snippets.txt.&nbsp; Code is not shown here for brevity.
</li><li>When the Physics Helper Library does its magic, it translates existing UI Elements into PhysicsSprite objects. So what if we want to get at the original controls, perhaps to execute a StoryBoard that we defined on them? We can do this by using the FindName
 method to get the original user control instance. So, add the code below, which we'll use to get a reference to the Puck Storyboard “sbLostPuck”.
<pre class="csharpcode">ucPuck GetPuckControl(<span class="kwrd">string</span> spriteName)
{
    ucPuck puck;
    var parent = PhysicsControllerMain.ParentCanvas;
    <span class="kwrd">switch</span> (spriteName)
    {
        <span class="kwrd">case</span> <span class="str">&quot;Puck&quot;</span>:
            puck = parent.FindName(<span class="str">&quot;bluePuck1&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> <span class="str">&quot;Puck_1&quot;</span>:
            puck = parent.FindName(<span class="str">&quot;bluePuck2&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> <span class="str">&quot;Puck_2&quot;</span>:
            puck = parent.FindName(<span class="str">&quot;bluePuck3&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> <span class="str">&quot;Puck_3&quot;</span>:
            puck = parent.FindName(<span class="str">&quot;redPuck1&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> <span class="str">&quot;Puck_4&quot;</span>:
            puck = parent.FindName(<span class="str">&quot;redPuck2&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
        <span class="kwrd">default</span>:
            puck = parent.FindName(<span class="str">&quot;redPuck3&quot;</span>) 
                    <span class="kwrd">as</span> ucPuck;
            <span class="kwrd">break</span>;
    }

    <span class="kwrd">return</span> puck;
}</pre>
</li><li>Finally, to score, we'll determine if the puck lies between any of the Rectangles in the end zone.
<br>
This code is the snippet “Get Points for Puck” in snippets.txt.
<pre class="csharpcode"><span class="kwrd">int</span> GetPointsForPuck(PhysicsSprite puck)
{
    <span class="kwrd">int</span> score = 0;
    Vector2 puckPos = puck.BodyObject.Position;

    <span class="kwrd">double</span> left = Convert.ToDouble(
        rectPoints3.GetValue(Canvas.LeftProperty));
    <span class="kwrd">double</span> top = Convert.ToDouble(
        rectPoints3.GetValue(Canvas.TopProperty));

    <span class="kwrd">if</span> ((puckPos.X &gt; left &amp;&amp; puckPos.X &lt; left &#43; rectPoints3.Width) 
     &amp;&amp; (puckPos.Y &gt; top &amp;&amp; puckPos.Y &lt; top &#43; rectPoints3.Height))
        score = 3;

    left = Convert.ToDouble(rectPoints2.GetValue(Canvas.LeftProperty));
    top = Convert.ToDouble(rectPoints2.GetValue(Canvas.TopProperty));
    <span class="kwrd">if</span> ((puckPos.X &gt; left &amp;&amp; puckPos.X &lt; left &#43; rectPoints2.Width) 
     &amp;&amp; (puckPos.Y &gt; top &amp;&amp; puckPos.Y &lt; top &#43; rectPoints2.Height))
        score = 2;

    left = Convert.ToDouble(rectPoints1.GetValue(Canvas.LeftProperty));
    top = Convert.ToDouble(rectPoints1.GetValue(Canvas.TopProperty));
    <span class="kwrd">if</span> ((puckPos.X &gt; left &amp;&amp; puckPos.X &lt; left &#43; rectPoints1.Width) 
     &amp;&amp; (puckPos.Y &gt; top &amp;&amp; puckPos.Y &lt; top &#43; rectPoints1.Height))
        score = 1;

    <span class="kwrd">return</span> score;
}</pre>
</li></ol>
<h3>Implement the “Game Loop”</h3>
<p>Most games are controlled by a “Game Loop” that executes many times per second. Within this Game Loop, we can check for collisions, perform enemy AI, and scoring. The PhysicsController fires an event called “TimerLoop” that we can use for this purpose.</p>
<ol>
<li>Replace the existing TimerLoop and Collision events with the following code snippet, which checks to see if any pucks have been shot and if we are ready for the next shot. Do this by seeing if the puck velocity has slowed down to nearly a stop…
<br>
This code is snippet “<b>Timer Loop</b>” inside snippets.txt.
<pre class="csharpcode"><span class="kwrd">void</span> _physicsController_TimerLoop(<span class="kwrd">object</span> source)
{
    <span class="rem">// check to see if the current shot is completed</span>
    <span class="kwrd">if</span> (_currentPuckShot &gt;= 0)
    {
    var puck = _pucks[_currentPuckShot].BodyObject;

        <span class="kwrd">if</span> (puck.Enabled == <span class="kwrd">false</span> ||
          Math.Abs(puck.LinearVelocity.X) &lt; 3                                   
          &amp;&amp; 
          Math.Abs(puck.LinearVelocity.Y) &lt; 3)
        {
            <span class="rem">// did the shot clear the end zone?</span>
            <span class="kwrd">if</span> (!PointWithinBounds(
              <span class="kwrd">new</span> Point(puck.Position.X, 
                       puck.Position.Y)))
            {
                _currentPuckShot = -1;
                _currentPuckToShoot&#43;&#43;;
                SetupThePuck();
            }
        }
    }
}

<span class="kwrd">void</span> _physicsController_Collision(<span class="kwrd">string</span> sprite1, <span class="kwrd">string</span> sprite2)
{
    <span class="rem">// check for puck off sides</span>
    <span class="kwrd">if</span> (sprite1.StartsWith(<span class="str">&quot;rectSensor&quot;</span>) &amp;&amp; sprite2.StartsWith(<span class="str">&quot;Puck&quot;</span>))
    {
        ucPuck puck = GetPuckControl(sprite2);

        _physicsController.PhysicsObjects[sprite2].
            BodyObject.Enabled = <span class="kwrd">false</span>;

        puck.sbLostPuck.Begin();
    }
}</pre>
</li></ol>
<h3>Targeting Windows Phone</h3>
<p>So far, we've created a Silverlight 3, web-based version of a shuffleboard game. Next we'll quickly port this to Windows Phone, taking advantage of some of the platform's capabilities, such as multitouch. We'll do this by using
<i>linked files</i> that point back to our existing Silverlight 3 project.</p>
<ol>
<li>Right-click the Silverlight solution in Blend and select Add New Project. </li><li>Select Windows Phone Application and enter <b>ShuffleBoard.WindowsPhone</b> for the name.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/6266.image_5F00_0B758EEE.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8738.image_5F00_thumb_5F00_51F27EF6.png" width="416" height="382"></a>
</li><li>Delete the <b>TitleGrid</b> and <b>ContentGrid</b> elements from the Objects and Timeline Panel.
</li><li>Convert LayoutRoot to a Canvas by right-clicking it and selecting Change Layout Type/Canvas.
</li><li>Right-click the project and select Add Reference. Browse to the following assemblies located in the sample download (these are the WindowsPhone versions of the Physics Helper and Farseer):
<br>
<br>
\ShuffleBoard.WindowsPhone\Bin\Debug\FarseerPhysics.dll <br>
\ShuffleBoard.WindowsPhone\Bin\Debug\Spritehand.FarseerHelper.dll <br>
\ShuffleBoard.WindowsPhone\Bin\Debug\Spritehand.PhysicsBehaviors.dll <br>
</li><li>We need references to the assemblies used for Behaviors. An easy way to do this is to add a Behavior to an element and then delete it. From the Assets panel, drag a PhysicsControllerBehavior onto LayoutRoot and then delete it. Note that this adds a reference
 to System.Windows.Interactivity to the project. </li><li>Next, we'll add in the linked files from the existing Silverlight 3 project. Right-click the ShuffleBoard.WindowsPhone project and select Add/Link to Existing Item. Select the following files:
<ol>
<li>ucMainGame.xaml </li><li>ucMainGame.xaml.cs </li><li>ucPlayerUp.xaml </li><li>ucPlayerUp.xaml.cs </li><li>ucPuck.xaml </li><li>ucPuck.xaml.cs </li><li>ucScoreBoard.xaml </li><li>ucScoreBoard.xaml.cs </li></ol>
</li><li>8. Add a new folder to the project named images. </li><li>9. Right-click the images folder and select Link to Existing item, then navigate to the following image in the sample folder:
<br>
\ShuffleBoard\images\shuffleboardTable.jpg <br>
</li><li>Build the project by clicking Ctrl&#43;Shift&#43;B. </li><li>From the Assets Panel, under Controls/All, find ucMainGame and drag an instance onto LayoutRoot. Set the Left and Top properties to 0.
</li><li>Right-click the WindowsPhone project and select “Startup” to set this as the startup project.
</li><li>Run the project by clicking F5. </li></ol><p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/5/0/2/6/5/5/ShuffleboardPart4_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/5/0/2/6/5/5/ShuffleboardPart4_512_ch9.png, postid=556205" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p><h3>Windows Phone Touch Input</h3>
<p>So far, we've used a simple mouse-event-based input mechanism for shooting the pucks. But on the Windows Phone 7 platform, we can do better than that by using Multitouch events. These events include an inertia property that will make our puck physics more
 realistic.</p>
<ol>
<li>Since we are going to need to support two different platforms now (Web and Windows Phone), we need to introduce a Conditional Compilation Symbol so that the compiler can differentiate between each platform's code.
</li><li>Open the solution inside Visual Studio by right-clicking it in the Projects Panel and then select “Edit in Visual Studio”
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/0410.image_5F00_7F739EB9.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/4604.image_5F00_thumb_5F00_78546241.png" width="215" height="189"></a>
</li><li>Right-click the ShuffleBoard.WindowsPhone Project and select Properties. </li><li>4. Add in a new compilation symbol for WINDOWS_PHONE. <br>
NOTE: Future releases of WP7 Tools will likely define a default compilation symbol, so you may already see one defined here.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/6366.image_5F00_713525C9.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10025512/8726.image_5F00_thumb_5F00_09C4C31A.png" width="550" height="128"></a>
</li><li>Now we'll add in the Windows Phone-specific events for manipulation using touch. Open ucMainGame.xaml.cs and find the _physicsController_Initialized event handler. Replace the events for the mouse events with the following, which will wire up either the
 manipulation events (for Windows Phone) or the mouse events (for Silverlight Web):
<br>
This code is snippet “<b>Manipulation Events</b>” inside snippets.txt.
<pre class="csharpcode"><span class="preproc">#if</span> WINDOWS_PHONE
    puck.ManipulationStarted &#43;= 
      <span class="kwrd">new</span> EventHandler&lt;ManipulationStartedEventArgs&gt;
      (puck_ManipulationStarted);
    puck.ManipulationCompleted &#43;= 
      <span class="kwrd">new</span> EventHandler&lt;ManipulationCompletedEventArgs&gt;
      (puck_ManipulationCompleted);
    puck.ManipulationDelta &#43;= 
      <span class="kwrd">new</span> EventHandler&lt;ManipulationDeltaEventArgs&gt;
      (puck_ManipulationDelta);
<span class="preproc">#else</span>
    puck.MouseLeftButtonDown &#43;= 
      <span class="kwrd">new</span> MouseButtonEventHandler(puck_MouseLeftButtonDown);
    puck.MouseMove &#43;= 
      <span class="kwrd">new</span> MouseEventHandler(puck_MouseMove);
    puck.MouseLeftButtonUp &#43;= 
      <span class="kwrd">new</span> MouseButtonEventHandler(puck_MouseLeftButtonUp);
<span class="preproc">#endif</span></pre>
</li><li>Now we just need to implement those event handlers for manipulation. The main consideration here is that the ManipulationCompleted event passes in a FinalVelocity.LinearVelocity parameter, which we can use to create realistic physics from the user's shot:
<p>Add the code snippet “Manipulation Event Handlers” from snippets.txt</p>
<pre class="csharpcode">Vector2 force = <span class="kwrd">new</span> Vector2(
    (<span class="kwrd">float</span>)(e.FinalVelocities.LinearVelocity.X * scalePower), 
    (<span class="kwrd">float</span>)(e.FinalVelocities.LinearVelocity.Y * scalePower));</pre>
</li><li>Run the project by clicking F5, and try sliding some pucks. </li></ol>
<h3>Performance</h3>
<p>Depending on your configuration, you may experience poor performance for the shuffleboard game when running it in the Windows Phone emulator. There are different reasons for this, including video card drivers and virtualization settings. Please refer to
<a href="http://www.andybeaulieu.com/Home/tabid/67/EntryID/196/Default.aspx">this blog post</a>, which details these performance considerations.</p>
<ol>
<li>1. Inside the ucMainGame constructor, let's turn on the Frame Rate counter so we can see our current frame rate. This code is snippet “Frame Rate Counter” inside snippets.txt
<pre class="csharpcode">Application.Current.Host.Settings.EnableFrameRateCounter = <span class="kwrd">true</span>;</pre>
</li><li>Run the project by hitting F5, and note the current frame rate. <br>
<b>NOTE: Your development configuration may prevent you from having an adequate framerate in the Windows Phone Emulator! Please refer to
</b><a href="http://www.andybeaulieu.com/Home/tabid/67/EntryID/196/Default.aspx"><b>this blog post</b></a><b> for tips on emulator performance.</b>
</li></ol>
<p>One performance tweak we can easily make is taking advantage of hardware acceleration. Silverlight enables us to use the video card to render elements, which can greatly increase performance. To do this, we add a Cachemode=”BitmapCache” attribute to any
 elements we want to hardware accelerate.</p>
<ol>
<li>Open ucPuck.xaml and note that there is a CacheMode attribute on the Puck Canvas.
</li><li>Open ucMainGame.xaml and add a CacheMode attribute to the cnvTable Canvas element.
<pre class="csharpcode">&lt;Canvas x:Name=<span class="str">&quot;cnvTable&quot;</span> Width=<span class="str">&quot;480&quot;</span> Height=<span class="str">&quot;800&quot;</span> 
d:LayoutOverrides=<span class="str">&quot;Width, Height&quot;</span> CacheMode=<span class="str">&quot;BitmapCache&quot;</span>&gt;</pre>
</li><li>Run the project and note the frame rate change. </li></ol>
<p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/5/1/2/6/5/5/ShuffleboardPart6_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/5/1/2/6/5/5/ShuffleboardPart6_512_ch9.png, postid=556215" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p>
<h3>Adding Sound</h3>
<p>Sound is one area where Windows Phone and Web Silverlight differ a bit. Under Silverlight for Web, we can use the MediaElement class to play back WMA and MP3 format audio. Multiple instances of the MediaElement class can be played simultaneously, and the
 sound output will be automatically mixed.</p>
<p>However, on Windows Phone we have access to the XNA game libraries, including sound support. This is a much more efficient way to add mixed sound to a Silverlight game on Windows Phone, but it only supports WAV format sound files.
</p>
<p>The Physics Helper Library has a useful class wrapper for sounds, which we'll use to play a “hit puck” sound on both platforms.</p>
<ol>
<li>In the ShuffleBoard (Silverlight Web) project, right-click and select Add Folder.
</li><li>Name the folder sounds. </li><li>Add an existing item to the sounds folder from this location: <br>
\ShuffleBoard\ShuffleBoard\sounds\hitPuck.wma </li><li>Set the Build Action of the file to Content. </li><li>In the ShuffleBoard.WindowsPhone project, right-click and select Add Folder. </li><li>Name the folder sounds. </li><li>Add an existing item to the sounds folder from this location: <br>
\ShuffleBoard.WindowsPhone\sounds\hitPuck.wav </li><li>Set the Build Action of the file to Content. </li><li>Inside ucMainGame.xaml.cs, add a class-level declaration for a SoundMain class (this is defined in the Physics Helper Library):
<br>
This snippet is “<b>Declare the Sound</b>” inside snippets.txt.
<pre class="csharpcode">SoundMain _soundPuckHit;</pre>
</li><li>10. Inside the ucMainGame_Loaded event, add code to declare the two sounds. Note that Windows Phone uses a WAV format sound without a “/” prefix for the root.
<br>
This snippet is “<b>Declare the Sound</b>” inside snippets.txt.
<pre class="csharpcode"><span class="preproc">#if</span> WINDOWS_PHONE
    _soundPuckHit = <span class="kwrd">new</span> SoundMain(<span class="kwrd">this</span>.LayoutRoot,
                   <span class="str">&quot;sounds/hitPuck.wav&quot;</span>, 2, 0);
<span class="preproc">#else</span>
    _soundPuckHit = <span class="kwrd">new</span> SoundMain(<span class="kwrd">this</span>.LayoutRoot, 
                   <span class="str">&quot;/sounds/hitPuck.wma&quot;</span>, 2, 0);
<span class="preproc">#endif</span></pre>
</li><li>Inside the _physicscontroller_collision event, add code to play the sound if a puck-to-puck collision occurs and the velocity is &gt; 10:
<br>
This snippet is “<b>Play the Sound</b>” inside snippets.txt.
<pre class="csharpcode"><span class="rem">// check for puck to puck collsion</span>
<span class="kwrd">if</span> (sprite1.StartsWith(<span class="str">&quot;Puck&quot;</span>) &amp;&amp; sprite2.StartsWith(<span class="str">&quot;Puck&quot;</span>))
{
    PhysicsSprite sprite = _physicsController.PhysicsObjects[sprite1];

    <span class="kwrd">if</span> (Math.Abs(sprite.BodyObject.LinearVelocity.X) &gt; 10
        || Math.Abs(sprite.BodyObject.LinearVelocity.Y) &gt; 10)
    {
        _soundPuckHit.Play();
    }
}</pre>
</li><li>Run the project and try hitting pucks together. </li></ol>
<p align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="384">
<param name="source" value="http://channel9.msdn.com/App_Themes/default/VideoPlayer10_01_18.xap" />
<param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/9/0/2/6/5/5/ShuffleboardPart5_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/9/0/2/6/5/5/ShuffleboardPart5_512_ch9.png, postid=556209" />
<param name="background" value="#00FFFFFF" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object></p>
<h3>Summary</h3>
<p>Since the 1.1 Alpha release, Silverlight has offered a compelling casual game development environment. With the addition of Windows Phone, along with demos of Silverlight running on other embedded devices, you can bet the future of Silverlight for gaming
 is bright.</p>
<p>Here are a few resources for more information:</p>
<blockquote>
<p>Andy's blog <br>
<a href="http://www.andybeaulieu.com">http://www.andybeaulieu.com</a></p>
<p>Andy's Silverlight Demos <br>
<a href="http://www.spritehand.com">http://www.spritehand.com</a></p>
<p>The Physics Helper Library <br>
<a href="http://physicshelper.codeplex.com">http://physicshelper.codeplex.com</a></p>
<p>Great free resource for learning Expression Blend and Silverlight <br>
<a href="http://www.microsoft.com/design/toolbox/">http://www.microsoft.com/design/toolbox/</a></p>
</blockquote>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:30175390e92d402d81c69e7600c925c0">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Creating-a-Shuffleboard-Game-using-Silverlight</comments>
      <itunes:summary>In this walkthrough, we will create a 
table shuffleboard style game for Windows Phone 7 using Silverlight. Many bars feature these long wooden table games, in which players slide metal pucks down the length of the table, attempting to get as close as possible to the far end without sliding
 off the edge.


 Multi-Targeting
Windows Phone 7 uses a version of Silverlight 3 with a few bonus features. Because this version of Silverlight is so close to the Web version of Silverlight 3, we&#39;ll take the approach of
Multitargeting a solution for both platforms. To do so, start with a Silverlight 3 (web) application template, and then add in a Windows Phone project with linked files that re-use the Silverlight 3 solution. This allows us to deploy to many different
 platforms using the same code base.
Let&#39;s get started by creating our Solution in this way.
Creating the Solution and MainPage

In Expression Blend 4, create a new Silverlight Application &amp;#43; Website template named Shuffleboard. Be sure to select “3.0” from the Version dropdown, as this is what is supported by Windows Phone (in a little bit we&#39;ll add in the Windows Phone project template
 as well). 

In the Objects and Timeline Panel, select the main UserControl and set its Width to 480 and its Height to 800. This is the size of a Windows Phone UI in Portrait mode.
Select the LayoutRoot Grid and set its Width to 480 and its Height to 800. For games, a Canvas layout container is better than a Grid, so let&#39;s change the LayoutRoot container type. Right-click LayoutRoot and select Change Layout Type/Canvas.


Since some parts of our UI can appear outside of the game area, we want to add a Clip to this main canvas so that the user does not see these outside elements. Add the following just under the LayoutRoot Canvas:

This XAML is snippet “MainPage Clip” inside snippets.txt.
&amp;lt;Canvas.Clip&amp;gt;
    &amp;lt;RectangleGeometry Rect=&amp;quot;0,0,480,800&amp;quot;/&amp;gt;
&amp;lt;/Canvas.Clip&amp;gt;


We&#39;ll be using some pre-built Behaviors t</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Creating-a-Shuffleboard-Game-using-Silverlight</link>
      <pubDate>Tue, 15 Jun 2010 21:23:23 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Creating-a-Shuffleboard-Game-using-Silverlight</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10025512_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10025512_220.jpg" height="165" width="220"/>      
      <dc:creator>Andy Beaulieu </dc:creator>
      <itunes:author>Andy Beaulieu </itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Creating-a-Shuffleboard-Game-using-Silverlight/RSS</wfw:commentRss>
      <category>Expression Blend</category>
      <category>Gaming</category>
      <category>Mobile</category>
      <category>Physics</category>
      <category>Silverlight</category>
      <category>Windows Phone</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Victor Gaudioso talks Silverlight 4 with Murray Gordon at MIX10</title>
      <description><![CDATA[Victor Gaudioso talks to Murray Gordon from Microsoft about building compelling user interfaces using Silverlight 4.<br /><br />Enjoy the show!<br /><br /><b>John O'Donnell</b> Microsoft Dynamics ISV Architect Evangelist<br />Microsoft Corporation<br /><a shape="rect" href="http://blogs.msdn.com/jodonnell" shape="rect">http://blogs.msdn.com/jodonnell<br /></a><a shape="rect" href="http://blogs.msdn.com/usisvde" shape="rect">http://blogs.msdn.com/usisvde</a><br /><a shape="rect" href="http://www.twitter.com/jodonnel" shape="rect">http://www.twitter.com/jodonnel</a>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:0e4099bbfe0340e1a8079deb00081d03">]]></description>
      <comments>http://channel9.msdn.com/Blogs/jodonnell/Victor-Gaudioso-talks-Silverlight-4-with-Murray-Gordon-at-MIX10</comments>
      <itunes:summary>Victor Gaudioso talks to Murray Gordon from Microsoft about building compelling user interfaces using Silverlight 4.Enjoy the show!John O&#39;Donnell Microsoft Dynamics ISV Architect EvangelistMicrosoft Corporationhttp://blogs.msdn.com/jodonnellhttp://blogs.msdn.com/usisvdehttp://www.twitter.com/jodonnel
</itunes:summary>
      <itunes:duration>408</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/jodonnell/Victor-Gaudioso-talks-Silverlight-4-with-Murray-Gordon-at-MIX10</link>
      <pubDate>Tue, 11 May 2010 15:51:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/jodonnell/Victor-Gaudioso-talks-Silverlight-4-with-Murray-Gordon-at-MIX10</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/549309_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/549309_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_320_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_512_ch9.png" height="384" width="512"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_85_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_2MB_ch9.wmv" expression="full" duration="408" fileSize="52824709" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_ch9.mp3" expression="full" duration="408" fileSize="3272601" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_ch9.mp4" expression="full" duration="408" fileSize="57565921" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_ch9.wma" expression="full" duration="408" fileSize="3312383" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_ch9.wmv" expression="full" duration="408" fileSize="80747247" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_Zune_ch9.wmv" expression="full" duration="408" fileSize="54283299" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/9/0/3/9/4/5/VictorGaudiosoMix10_ch9.wmv" length="80747247" type="video/x-ms-wmv"/>
      <dc:creator>John O&#39;Donnell</dc:creator>
      <itunes:author>John O&#39;Donnell</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/jodonnell/Victor-Gaudioso-talks-Silverlight-4-with-Murray-Gordon-at-MIX10/RSS</wfw:commentRss>
      <category>.NET Framework 4.0</category>
      <category>2010</category>
      <category>Expression Blend</category>
      <category>Silverlight 4</category>
      <category>Visual Studio 2010</category>
      <category>Windows Phone 7 Series</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>MSDN Radio: Expression, Poetry, and the Windows Phone</title>
      <description><![CDATA[Modern User Interface design and development has been significantly impacted by the features and capabilities of Microsoft XAML. Fortunately the tools team has been active in providing great solutions for harnessing the power of great design with the release
 of the Microsoft Expression suite. We talk with Christian Schormann from the Microsoft Expression team about music, poetry, and some great design patterns.
<p>&nbsp;</p>
<p>MSDN Radio is a weekly Developer talk-show that helps answer your questions about the latest Microsoft news, solutions, and technologies. We dive into the challenges of deciphering today’s technology stack. Visit
<a shape="rect" href="http://www.MSDNRadio.com" shape="rect">www.MSDNRadio.com</a> to register for upcoming shows.<br /><b><br />Host and Guest: </b>Mike Benkovich, Senior Developer Evangelist, and Christian Schormann, Program Manager, Microsoft Corporation</p>
<p>Mike Benkovich delivers technical presentations around the U.S. as a developer tools evangelist on the MSDN team at Microsoft. He has worked in a variety of professional roles, including architect, project manager, developer, and technical writer.<br /><br />You've seen him at MIX, PDC, and other conferences around the world. Christian's a toolmaker out of passion—the right tools give wings to our imagination. When he's not creating great music he's working at Microsoft on Expression Blend. Last year he introduced
 us to Sketchflow, we can't wait to see what's next!</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7f61903e453a404895079deb0030757a">]]></description>
      <comments>http://channel9.msdn.com/Blogs/egibson/MSDN-Radio-Expression-Poetry-and-the-Windows-Phone</comments>
      <itunes:summary>Modern User Interface design and development has been significantly impacted by the features and capabilities of Microsoft XAML. Fortunately the tools team has been active in providing great solutions for harnessing the power of great design with the release
 of the Microsoft Expression suite. We talk with Christian Schormann from the Microsoft Expression team about music, poetry, and some great design patterns.
&amp;nbsp;
MSDN Radio is a weekly Developer talk-show that helps answer your questions about the latest Microsoft news, solutions, and technologies. We dive into the challenges of deciphering today’s technology stack. Visit
www.MSDNRadio.com to register for upcoming shows.Host and Guest: Mike Benkovich, Senior Developer Evangelist, and Christian Schormann, Program Manager, Microsoft Corporation
Mike Benkovich delivers technical presentations around the U.S. as a developer tools evangelist on the MSDN team at Microsoft. He has worked in a variety of professional roles, including architect, project manager, developer, and technical writer.You&#39;ve seen him at MIX, PDC, and other conferences around the world. Christian&#39;s a toolmaker out of passion—the right tools give wings to our imagination. When he&#39;s not creating great music he&#39;s working at Microsoft on Expression Blend. Last year he introduced
 us to Sketchflow, we can&#39;t wait to see what&#39;s next!
</itunes:summary>
      <itunes:duration>1806</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/egibson/MSDN-Radio-Expression-Poetry-and-the-Windows-Phone</link>
      <pubDate>Mon, 26 Apr 2010 23:09:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/egibson/MSDN-Radio-Expression-Poetry-and-the-Windows-Phone</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/546551_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/546551_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_320_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_512_ch9.png" height="384" width="512"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_85_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_2MB_ch9.wmv" expression="full" duration="1806" fileSize="94824261" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_ch9.mp3" expression="full" duration="1806" fileSize="14456954" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_ch9.mp4" expression="full" duration="1806" fileSize="60797104" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_ch9.wma" expression="full" duration="1806" fileSize="14622443" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_ch9.wmv" expression="full" duration="1806" fileSize="47886819" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_Zune_ch9.wmv" expression="full" duration="1806" fileSize="43310871" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/1/5/5/6/4/5/MSDNRadioExpressionSchormann_ch9.wmv" length="47886819" type="video/x-ms-wmv"/>
      <dc:creator>MSDN Online Media</dc:creator>
      <itunes:author>MSDN Online Media</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/egibson/MSDN-Radio-Expression-Poetry-and-the-Windows-Phone/RSS</wfw:commentRss>
      <category>Christian Schormann</category>
      <category>Design Patterns</category>
      <category>Expression</category>
      <category>Expression 3</category>
      <category>Expression Blend</category>
      <category>MSDNRadio</category>
      <category>SketchFlow</category>
      <category>talk-radio</category>
      <category>Windows Phone</category>
      <category>XAML</category>
    </item>
  <item>
      <title>XAML Playground - A Designer built in Silverlight using Gestalt</title>
      <description><![CDATA[Karsten Januszewski has posted a <a shape="rect" href="http://www.rhizohm.net//irhetoric/blog/98/default.aspx" shape="rect">
write up on his XAML Playground </a>project, a design surface written in Silverlight using
<a shape="rect" href="http://www.visitmix.com/Labs/gestalt/" shape="rect">Gestalt</a>.&nbsp; The source code is available so you can see a glimpse into the work it takes to create a design tool.<br>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f20a0742ea3a40f7ad999deb00214fae">]]></description>
      <comments>http://channel9.msdn.com/Blogs/ContinuumNews/XAML-Playground-A-Designer-built-in-Silverlight-using-Gestalt</comments>
      <itunes:summary>Karsten Januszewski has posted a 
write up on his XAML Playground project, a design surface written in Silverlight using
Gestalt.&amp;nbsp; The source code is available so you can see a glimpse into the work it takes to create a design tool.
</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/ContinuumNews/XAML-Playground-A-Designer-built-in-Silverlight-using-Gestalt</link>
      <pubDate>Fri, 24 Jul 2009 17:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/ContinuumNews/XAML-Playground-A-Designer-built-in-Silverlight-using-Gestalt</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/480551_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/480551_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/28c6368d-eb5f-4362-b4cd-29234d13432b.jpg" height="210" width="280"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/adf44481-eded-4ff0-8f4f-b02d909c3ff7.jpg" height="64" width="85"/>      
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/ContinuumNews/XAML-Playground-A-Designer-built-in-Silverlight-using-Gestalt/RSS</wfw:commentRss>
      <category>Gestalt</category>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>A new version of the Fireworks to XAML Panel is available</title>
      <description><![CDATA[Grant Hinkson has a published an updated <a href="http://www.granthinkson.com/2009/07/23/updated-fireworks-to-xaml-panel-posted/">
Fireworks to XAML panel</a> which allows to output XAML from your Fireworks designs.&nbsp; The new version includes a new CS4 skin and additional features resulting in much cleaner XAML.<br>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d38dcd2b56d346f09e049deb002156c8">]]></description>
      <comments>http://channel9.msdn.com/Blogs/ContinuumNews/A-new-version-of-the-Fireworks-to-XAML-Panel-is-available</comments>
      <itunes:summary>Grant Hinkson has a published an updated 
Fireworks to XAML panel which allows to output XAML from your Fireworks designs.&amp;nbsp; The new version includes a new CS4 skin and additional features resulting in much cleaner XAML.
</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/ContinuumNews/A-new-version-of-the-Fireworks-to-XAML-Panel-is-available</link>
      <pubDate>Fri, 24 Jul 2009 16:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/ContinuumNews/A-new-version-of-the-Fireworks-to-XAML-Panel-is-available</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/480550_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/480550_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/8848c510-5c34-4ba5-9a82-33ebc04f00f7.jpg" height="210" width="280"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/cdb5fdee-a97d-4ae8-8e4c-ea2ff42ba17a.jpg" height="64" width="85"/>      
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/ContinuumNews/A-new-version-of-the-Fireworks-to-XAML-Panel-is-available/RSS</wfw:commentRss>
      <category>Expression Blend</category>
      <category>Silverlight</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Saving Silverlight XAML to a JPEG using WritableBitmap</title>
      <description><![CDATA[Blueboxes walks&nbsp;us&nbsp;through the process of <a shape="rect" href="http://blog.blueboxes.co.uk/2009/07/21/rendering-xaml-to-a-jpeg-using-silverlight-3/" title="Rendering XAML to a JPEG using Silverlight 3" shape="rect">
Rendering XAML to a JPEG using Silverlight 3</a>&nbsp;using the WritableBitmap class. Very useful when you wish to&nbsp;&quot;print&quot; the state of an application or something a user has created.
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:120f541b9ac643118f979deb00215ce1">]]></description>
      <comments>http://channel9.msdn.com/Blogs/ContinuumNews/Saving-Silverlight-XAML-to-a-JPEG-using-WritableBitmap</comments>
      <itunes:summary>Blueboxes walks&amp;nbsp;us&amp;nbsp;through the process of 
Rendering XAML to a JPEG using Silverlight 3&amp;nbsp;using the WritableBitmap class. Very useful when you wish to&amp;nbsp;&amp;quot;print&amp;quot; the state of an application or something a user has created.
</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/ContinuumNews/Saving-Silverlight-XAML-to-a-JPEG-using-WritableBitmap</link>
      <pubDate>Thu, 23 Jul 2009 00:14:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/ContinuumNews/Saving-Silverlight-XAML-to-a-JPEG-using-WritableBitmap</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/480374_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/480374_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/9a5b3a4b-abde-4fae-8c74-a39ea0a6517d.jpg" height="210" width="280"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/64096da5-cf2c-40e9-8a9d-b46a0c6f5f75.jpg" height="64" width="85"/>      
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/ContinuumNews/Saving-Silverlight-XAML-to-a-JPEG-using-WritableBitmap/RSS</wfw:commentRss>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Expression Studio 3 is now available!</title>
      <description><![CDATA[Expression Studio 3 includes four professional design tools with many worthy features worth checking out.&nbsp; Below I will pick just one new feature for each tool included.<br>
<br>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp; Expression Web 3</strong> - <a shape="rect" href="http://blogs.msdn.com/xweb/archive/2009/03/18/Microsoft-Expression-Web-SuperPreview-for-Windows-Internet-Explorer.aspx" shape="rect">
SuperPreview</a>, multi-browser visual debugging</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp; Expression Blend 3 &#43; SketchFlow</strong> - <a shape="rect" href="http://electricbeach.org/?p=214" shape="rect">
SketchFlow</a> along with Silverlight 3 support </p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp; Expression Design 3</strong> - <a shape="rect" href="http://www.microsoft.com/expression/products/Design_Features.aspx" shape="rect">
Improved Photoshop Import</a> </p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp; Expression Encoder 3</strong> - new <a shape="rect" href="http://www.microsoft.com/expression/products/Encoder_Features.aspx" shape="rect">
Screen capture functionality</a> </p>
An&nbsp;<a shape="rect" href="http://www.microsoft.com/expression/try-it/Default.aspx" shape="rect">Expression Studio 3 Trial Edition is available for download</a> right now.
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:0a76011673cb4c8dbd239deb0021683e">]]></description>
      <comments>http://channel9.msdn.com/Blogs/ContinuumNews/Expression-Studio-3-is-now-available</comments>
      <itunes:summary>Expression Studio 3 includes four professional design tools with many worthy features worth checking out.&amp;nbsp; Below I will pick just one new feature for each tool included.

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression Web 3 - 
SuperPreview, multi-browser visual debugging
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression Blend 3 &amp;#43; SketchFlow - 
SketchFlow along with Silverlight 3 support 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression Design 3 - 
Improved Photoshop Import 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression Encoder 3 - new 
Screen capture functionality 
An&amp;nbsp;Expression Studio 3 Trial Edition is available for download right now.
</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/ContinuumNews/Expression-Studio-3-is-now-available</link>
      <pubDate>Wed, 22 Jul 2009 17:32:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/ContinuumNews/Expression-Studio-3-is-now-available</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/480297_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/480297_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/3c17b3a5-8dd6-4fa6-a901-dc99225384a7.jpg" height="210" width="280"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/46e6b254-c534-44c1-9d68-03f2fab4067b.jpg" height="64" width="85"/>      
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/ContinuumNews/Expression-Studio-3-is-now-available/RSS</wfw:commentRss>
      <category>Expression</category>
      <category>Expression Blend</category>
      <category>Silverlight</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Gestalt - Nishant Kothary and Joshua Allen</title>
      <description><![CDATA[
<p>Not all Microsoft technologies and projects come out of large development teams with huge budgets and equally huge objectives. There are in fact a variety of very useful technologies which are fairly low-key and the result of small development efforts.<br>
<br>
&quot;Gestalt&quot; is a technology that allows web developers to easily include ruby, python, and even Silverlight code directly within the html of their websites. No fancy tools are necessary (or available at the moment). It also work cross platform and cross browser.
 The end result is rich and powerful web applications which are exceedingly easy to develop and deploy.<br>
<br>
In this episode I'll be talking with Nishant Kotharny and Joshua Allen to find out exactly why Gestalt is so cool, and after seeing their demo, I dare you not to want to check it out yourself.<br>
<br>
You can download Gestalt and kick the tires here:</p>
<ul>
<li><a shape="rect" href="http://www.visitmix.com/labs/gestalt/" shape="rect"><strong>Gestalt - A MIX Online Lab</strong></a>&nbsp;
</li></ul>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:621cc4bb71f14e589e6c9deb0171c2bc">]]></description>
      <comments>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Gestalt-Nishant-Kothary-and-Joshua-Allen</comments>
      <itunes:summary>
Not all Microsoft technologies and projects come out of large development teams with huge budgets and equally huge objectives. There are in fact a variety of very useful technologies which are fairly low-key and the result of small development efforts.

&amp;quot;Gestalt&amp;quot; is a technology that allows web developers to easily include ruby, python, and even Silverlight code directly within the html of their websites. No fancy tools are necessary (or available at the moment). It also work cross platform and cross browser.
 The end result is rich and powerful web applications which are exceedingly easy to develop and deploy.

In this episode I&#39;ll be talking with Nishant Kotharny and Joshua Allen to find out exactly why Gestalt is so cool, and after seeing their demo, I dare you not to want to check it out yourself.

You can download Gestalt and kick the tires here:

Gestalt - A MIX Online Lab&amp;nbsp;

</itunes:summary>
      <itunes:duration>1434</itunes:duration>
      <link>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Gestalt-Nishant-Kothary-and-Joshua-Allen</link>
      <pubDate>Tue, 21 Jul 2009 23:55:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Gestalt-Nishant-Kothary-and-Joshua-Allen</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/479261_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/479261_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_2MB_ch9.wmv" expression="full" duration="1434" fileSize="288388632" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_ch9.mp3" expression="full" duration="1434" fileSize="11473546" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_ch9.mp4" expression="full" duration="1434" fileSize="73067924" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_ch9.wma" expression="full" duration="1434" fileSize="23198873" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_ch9.wmv" expression="full" duration="1434" fileSize="181470047" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_Zune_ch9.wmv" expression="full" duration="1434" fileSize="98702027" type="video/x-ms-wmv" medium="video"/>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_s_ch9.wmv" expression="full" duration="1434" fileSize="207" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/6/2/9/7/4/TKC017Gestalt_ch9.wmv" length="181470047" type="video/x-ms-wmv"/>
      <dc:creator>Robert Hess</dc:creator>
      <itunes:author>Robert Hess</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Gestalt-Nishant-Kothary-and-Joshua-Allen/RSS</wfw:commentRss>
      <category>Gestalt</category>
      <category>Python</category>
      <category>Ruby</category>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>XAML in .NET 4</title>
      <description><![CDATA[This isn't your Grandpa's XAML!<br>
<br>
XAML in .NET 4 is much more than just a Reader and Writer and also is now being consumed by many technologies including Silverlight, WCF, WF and of course WPF.&nbsp;<a shape="rect" href="http://blogs.windowsclient.net/rob_relyea/default.aspx" shape="rect">Rob Relyea</a>
 and Mike Shim came by to talk about what's new in XAML for 2009 and beyond.<br>
<br>
For instructions on how to download and <a shape="rect" href="http://channel9.msdn.com/shows/10-4/10-4-Episode-20-Downloading-and-Installing-Visual-Studio-2010-Beta-1/" shape="rect">
install Visual Studio 2010 Beta 1 check out this episode of 10-4</a>.  <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:beb95ac0b9b94e0883469deb001c441c">]]></description>
      <comments>http://channel9.msdn.com/Shows/Continuum/XAMLinNET4</comments>
      <itunes:summary>This isn&#39;t your Grandpa&#39;s XAML!

XAML in .NET 4 is much more than just a Reader and Writer and also is now being consumed by many technologies including Silverlight, WCF, WF and of course WPF.&amp;nbsp;Rob Relyea
 and Mike Shim came by to talk about what&#39;s new in XAML for 2009 and beyond.

For instructions on how to download and 
install Visual Studio 2010 Beta 1 check out this episode of 10-4. </itunes:summary>
      <itunes:duration>1194</itunes:duration>
      <link>http://channel9.msdn.com/Shows/Continuum/XAMLinNET4</link>
      <pubDate>Thu, 21 May 2009 14:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/Continuum/XAMLinNET4</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/470011_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/470011_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_2MB_ch9.wmv" expression="full" duration="1194" fileSize="351781103" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_ch9.mp3" expression="full" duration="1194" fileSize="9553577" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_ch9.mp4" expression="full" duration="1194" fileSize="90878853" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_ch9.wma" expression="full" duration="1194" fileSize="19317705" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_ch9.wmv" expression="full" duration="1194" fileSize="72396601" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_Zune_ch9.wmv" expression="full" duration="1194" fileSize="122732581" type="video/x-ms-wmv" medium="video"/>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_s_ch9.wmv" expression="full" duration="1194" fileSize="207" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/1/0/0/7/4/TCSXAMLinNET4_ch9.wmv" length="72396601" type="video/x-ms-wmv"/>
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>24</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/Continuum/XAMLinNET4/RSS</wfw:commentRss>
      <category>Silverlight</category>
      <category>WCF</category>
      <category>WF</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Druckbetankung - Die Show :: Silverlight Teil IV</title>
      <description><![CDATA[Der vierte Teil unserer Silverlight-Serie &quot;Druckbetankung - Die Show&quot; dreht sich um das Aussengerüst einer Silverlight Applikation, und wie dieses dazu gebracht werden mit der eingebetteten Anwendung zu kommunizieren.<br>
Oliver Scheer und ich sprechen über die Parameterübergabe aus der HTML-Seite in Silverlight. Da gibt es einiges zu beachten und viel zu entdecken. So lässt sich am Beispiel unseres RSS-Readers die initial verwendete RSS-Url über die HTML-Seite übergeben, und
 abhängig davon weitere Elemente im XAML-Code ein- oder ausblenden.  <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ee01c6a585e548779c039deb016ebc60">]]></description>
      <comments>http://channel9.msdn.com/Blogs/kitano/Silverlight-Druckbetankung-Die-Show-Teil-IV</comments>
      <itunes:summary>Der vierte Teil unserer Silverlight-Serie &amp;quot;Druckbetankung - Die Show&amp;quot; dreht sich um das Aussenger&#252;st einer Silverlight Applikation, und wie dieses dazu gebracht werden mit der eingebetteten Anwendung zu kommunizieren.
Oliver Scheer und ich sprechen &#252;ber die Parameter&#252;bergabe aus der HTML-Seite in Silverlight. Da gibt es einiges zu beachten und viel zu entdecken. So l&#228;sst sich am Beispiel unseres RSS-Readers die initial verwendete RSS-Url &#252;ber die HTML-Seite &#252;bergeben, und
 abh&#228;ngig davon weitere Elemente im XAML-Code ein- oder ausblenden. </itunes:summary>
      <itunes:duration>1035</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/kitano/Silverlight-Druckbetankung-Die-Show-Teil-IV</link>
      <pubDate>Fri, 08 May 2009 06:58:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/kitano/Silverlight-Druckbetankung-Die-Show-Teil-IV</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/466869_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/466869_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_2MB_ch9.wmv" expression="full" duration="1035" fileSize="57686528" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_ch9.mp3" expression="full" duration="1035" fileSize="8287952" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_ch9.mp4" expression="full" duration="1035" fileSize="41670229" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_ch9.wma" expression="full" duration="1035" fileSize="16776321" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_ch9.wmv" expression="full" duration="1035" fileSize="43083653" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_Zune_ch9.wmv" expression="full" duration="1035" fileSize="41899633" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/9/6/8/6/6/4/DruckbetankungSilverlightTeil4_ch9.wmv" length="43083653" type="video/x-ms-wmv"/>
      <dc:creator>Jan Schenk</dc:creator>
      <itunes:author>Jan Schenk</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/kitano/Silverlight-Druckbetankung-Die-Show-Teil-IV/RSS</wfw:commentRss>
      <category>de-de</category>
      <category>Druckbetankung</category>
      <category>embed</category>
      <category>html</category>
      <category>object</category>
      <category>Parameter</category>
      <category>RSS</category>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>SharePoint for Developers Part 3 - Expression Blend and Silverlight</title>
      <description><![CDATA[SharePoint developers will likely use a variety of tools to build solutions.&nbsp; In this screencast,&nbsp;<a shape="rect" href="http://blogs.msdn.com/kaevans" shape="rect">Kirk Evans</a>&nbsp;demonstrates how to use Expression Blend 2 to create a Silverlight application
 from scratch, and how to extend its functionality using Visual Studio 2008.&nbsp; We won't be looking specifically at SharePoint in this screencast, but we will use this application in future screencasts to integrate with SharePoint.&nbsp;
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:86c7c0758f6b4b3fb1fd9deb000e80d1">]]></description>
      <comments>http://channel9.msdn.com/Blogs/kirke/SharePoint-for-Developers-Part-3-Expression-Blend-and-Silverlight</comments>
      <itunes:summary>SharePoint developers will likely use a variety of tools to build solutions.&amp;nbsp; In this screencast,&amp;nbsp;Kirk Evans&amp;nbsp;demonstrates how to use Expression Blend 2 to create a Silverlight application
 from scratch, and how to extend its functionality using Visual Studio 2008.&amp;nbsp; We won&#39;t be looking specifically at SharePoint in this screencast, but we will use this application in future screencasts to integrate with SharePoint.&amp;nbsp;
</itunes:summary>
      <itunes:duration>915</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/kirke/SharePoint-for-Developers-Part-3-Expression-Blend-and-Silverlight</link>
      <pubDate>Tue, 28 Apr 2009 18:42:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/kirke/SharePoint-for-Developers-Part-3-Expression-Blend-and-Silverlight</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/467100_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/467100_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_2MB_ch9.wmv" expression="full" duration="915" fileSize="33734217" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_ch9.mp3" expression="full" duration="915" fileSize="7328123" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_ch9.mp4" expression="full" duration="915" fileSize="27329837" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_ch9.wma" expression="full" duration="915" fileSize="14829729" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_ch9.wmv" expression="full" duration="915" fileSize="29402933" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_Zune_ch9.wmv" expression="full" duration="915" fileSize="28698913" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/0/0/1/7/6/4/sl2andblend2_ch9.wmv" length="29402933" type="video/x-ms-wmv"/>
      <dc:creator>Kirk Evans</dc:creator>
      <itunes:author>Kirk Evans</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/kirke/SharePoint-for-Developers-Part-3-Expression-Blend-and-Silverlight/RSS</wfw:commentRss>
      <category>Expression Blend</category>
      <category>MOSS</category>
      <category>Office</category>
      <category>Sharepoint</category>
      <category>Silverlight</category>
      <category>Silverlight 2</category>
      <category>Visual Studio</category>
      <category>VSeWSS</category>
      <category>Water Cooler</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Fireworks to XAML Panel</title>
      <description><![CDATA[Grant Hinkson, the Director of Experience Design at Infragistics, is a big fan of the creative tool from Adobe called Fireworks.&nbsp;An issue, or some people may say an opportunity, arose 3 years ago when he&nbsp;started to work on WPF projects.&nbsp; How can he use
 his favorite design tool with this new technology?&nbsp; Resourcefully, he ended up writing his own Panel for Fireworks that solved the problem.<br>
<br>
The&nbsp;<a shape="rect" href="http://www.granthinkson.com/2008/10/26/fireworks-to-xaml-panel-updates-cs4-silverlight-fixes/" shape="rect">Fireworks to XAML Panel</a> has since been updated to work with both WPF and Silverlight and is available for free for you
 to use.  <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:31ce8898ada049ecade49deb001c8674">]]></description>
      <comments>http://channel9.msdn.com/Shows/Continuum/Fireworks-to-XAML-Panel</comments>
      <itunes:summary>Grant Hinkson, the Director of Experience Design at Infragistics, is a big fan of the creative tool from Adobe called Fireworks.&amp;nbsp;An issue, or some people may say an opportunity, arose 3 years ago when he&amp;nbsp;started to work on WPF projects.&amp;nbsp; How can he use
 his favorite design tool with this new technology?&amp;nbsp; Resourcefully, he ended up writing his own Panel for Fireworks that solved the problem.

The&amp;nbsp;Fireworks to XAML Panel has since been updated to work with both WPF and Silverlight and is available for free for you
 to use. </itunes:summary>
      <itunes:duration>355</itunes:duration>
      <link>http://channel9.msdn.com/Shows/Continuum/Fireworks-to-XAML-Panel</link>
      <pubDate>Tue, 31 Mar 2009 22:50:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/Continuum/Fireworks-to-XAML-Panel</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/463262_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/463262_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_2MB_ch9.wmv" expression="full" duration="355" fileSize="83136077" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_ch9.mp3" expression="full" duration="355" fileSize="633" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_ch9.mp4" expression="full" duration="355" fileSize="31147088" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_ch9.wma" expression="full" duration="355" fileSize="5763657" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_ch9.wmv" expression="full" duration="355" fileSize="22487573" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_Zune_ch9.wmv" expression="full" duration="355" fileSize="42951553" type="video/x-ms-wmv" medium="video"/>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_s_ch9.wmv" expression="full" duration="355" fileSize="212" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/6/2/3/6/4/TCSFireworksXAML_ch9.wmv" length="22487573" type="video/x-ms-wmv"/>
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/Continuum/Fireworks-to-XAML-Panel/RSS</wfw:commentRss>
      <category>Blend</category>
      <category>Silverlight</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Mike Swanson - XAML Plugin for Adobe Illustrator</title>
      <description><![CDATA[Both of us freshly back from MIX09, Mike Swanson stops in to show us a plug in that he wrote which allows users of Adobe Illustrator to export their designs as XAML for either WPF or Silverlight.<br>
<br>
Working Smarter means taking advantage of both the tools and the training that you already know. By using a plugin such as what Mike is illustrating here, it allows Adobe Illustrator users to continue to use their favorite tool while also moving into the world
 of XAML.<br>
<br>
You can download the plug in from Mike's site here:<br>
<a shape="rect" href="http://www.mikeswanson.com/xamlexport/" shape="rect">http://www.mikeswanson.com/xamlexport/</a><br>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:80ad94811f4f41b4960c9deb0171e819">]]></description>
      <comments>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Mike-Swanson-XAML-Plugin-for-Adobe-Illustrator</comments>
      <itunes:summary>Both of us freshly back from MIX09, Mike Swanson stops in to show us a plug in that he wrote which allows users of Adobe Illustrator to export their designs as XAML for either WPF or Silverlight.

Working Smarter means taking advantage of both the tools and the training that you already know. By using a plugin such as what Mike is illustrating here, it allows Adobe Illustrator users to continue to use their favorite tool while also moving into the world
 of XAML.

You can download the plug in from Mike&#39;s site here:
http://www.mikeswanson.com/xamlexport/
</itunes:summary>
      <itunes:duration>999</itunes:duration>
      <link>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Mike-Swanson-XAML-Plugin-for-Adobe-Illustrator</link>
      <pubDate>Fri, 27 Mar 2009 13:24:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Mike-Swanson-XAML-Plugin-for-Adobe-Illustrator</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/462548_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/462548_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_2MB_ch9.wmv" expression="full" duration="999" fileSize="301803939" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_ch9.mp3" expression="full" duration="999" fileSize="7993597" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_ch9.mp4" expression="full" duration="999" fileSize="97346470" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_ch9.wma" expression="full" duration="999" fileSize="16166509" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_ch9.wmv" expression="full" duration="999" fileSize="59739437" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_Zune_ch9.wmv" expression="full" duration="999" fileSize="78715417" type="video/x-ms-wmv" medium="video"/>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_s_ch9.wmv" expression="full" duration="999" fileSize="214" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/4/5/2/6/4/TKC008MikeSwanson_ch9.wmv" length="59739437" type="video/x-ms-wmv"/>
      <dc:creator>Robert Hess</dc:creator>
      <itunes:author>Robert Hess</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/The+Knowledge+Chamber/Mike-Swanson-XAML-Plugin-for-Adobe-Illustrator/RSS</wfw:commentRss>
      <category>Adobe Illustrator</category>
      <category>Mike Swanson</category>
      <category>XAML</category>
    </item>
  <item>
      <title>This Week: Martin Woodward, MVP Summit, Web Perf, Show Off, and a VSTS Pep Talk</title>
      <description><![CDATA[This week on Channel 9, Dan and Brian are joined by MVP&nbsp;<a href="http://woodwardweb.com/">Martin Woodward</a>&nbsp;to discuss this week's news, including:<br>
<br>
- Martin talks about the <a href="http://blogs.msdn.com/willy-peter_schaub/archive/2009/03/05/mvp-global-summit-photos.aspx">
MVP Summit </a>and how hewon the Team System MVP of the year. The prize, a&nbsp;pimp belt<br>
- Phil Haack:&nbsp;<a href="http://haacked.com/archive/2009/03/03/aspnetmvc-changes-for-rc2.aspx ">ASP.NET MVC RC 2</a>
<br>
-&nbsp;Tutorial: How to enable&nbsp;<a href="http://smallworkarounds.blogspot.com/2009/01/aspnet-iis-tricks-using-gzip.html">Gzip compression on IIS 6.0</a>&nbsp;to get ~70% smaller file size<br>
- Viktar Karpach - Getting an &quot;A&quot; Grade with <a href="http://www.karpach.com/yslow-and-asp-net-100-points-a-grade.htm">
ASP.NET using YSlow and Firebug</a><br>
- Erik Meijer and Charles Torre&nbsp;interview <a href="http://channel9.msdn.com/shows/Going&#43;Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/">
Anders Hejlsberg&nbsp;on the future of C#</a><br>
- Michael Kennedy -&nbsp;<a href="http://www.ubbuzz.com">ubbuzz.com</a> A custom Twitter watcher for .NET&nbsp;developers
<br>
- Jamie and Long start the <a href="http://channel9.usertaskforce.com/">Channel 9 Task Force</a>&nbsp;for bugs and suggestions<br>
- 1 week left for <a href="http://2009.visitmix.com/MIXtify/ShowOff.aspx">Show Off Contest</a><br>
- Vincent Rithner -&nbsp;<a href="http://www.sobees.com/">Sobees, A free WPF Social Desktop Aggregator</a>, Beta now available<br>
- Rob Relyea -&nbsp;<a href="http://blogs.windowsclient.net/rob_relyea/archive/2009/02/26/xaml-state-of-the-union-feb-2009.aspx">XAML State of the Union</a><br>
-&nbsp;<a href="http://caliburn.codeplex.com/">Caliburn Application Framework</a> for WPF and Silverlight(via
<a href="http://www.alvinashcraft.com/2009/02/27/dew-drop-february-27-2009/">Alvin Ashcraft</a>)<br>
- Tess Ferrandez -&nbsp;<a href="http://blogs.msdn.com/tess/archive/2009/03/04/silverlight-game-part-1-creating-the-main-layout.aspx">5-part series on building a Silverlight Game</a><br>
-&nbsp;<a href="http://www.liveside.net/main/archive/2009/02/28/windows-live-frameit-updated-to-new-look-for-all-sdk-now-available-for-download.aspx">Live FrameIt SDK</a> - Picasa and Photobucket integration<br>
- Martin's pick of the week: <a href="http://www.microsoft.com/visualstudio/en-us/products/teamsystem/default.mspx">
Send a VSTS Pep Talk to your teammates</a><br>
- Brian's pick of the week: <a href="http://www.hanselman.com/blog/QuakeLiveReviewAndRantWhyIsThisInteresting.aspx">
Scott Hanselman's analysis of Quake Live</a>, it isn't a Web game<br>
- Dan's pick of the week:&nbsp;<a href="http://www.brianpeek.com">Brian Peek's</a> tip on how to force a 64-bit exe that uses a 32-bit dependencies to load the
<a href="http://twitter.com/danielfe/status/1282431466">32-bit CLR</a>. <br>
<br>
<br>
<br>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d44e5a40b33c428fa9e29dea00c4d3d2">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/This-Week-Martin-Woodward-MVP-Summit-Web-Perf-Show-Off-and-a-VSTS-Pep-Talk</comments>
      <itunes:summary>This week on Channel 9, Dan and Brian are joined by MVP&amp;nbsp;Martin Woodward&amp;nbsp;to discuss this week&#39;s news, including:

- Martin talks about the 
MVP Summit and how hewon the Team System MVP of the year. The prize, a&amp;nbsp;pimp belt
- Phil Haack:&amp;nbsp;ASP.NET MVC RC 2

-&amp;nbsp;Tutorial: How to enable&amp;nbsp;Gzip compression on IIS 6.0&amp;nbsp;to get ~70% smaller file size
- Viktar Karpach - Getting an &amp;quot;A&amp;quot; Grade with 
ASP.NET using YSlow and Firebug
- Erik Meijer and Charles Torre&amp;nbsp;interview 
Anders Hejlsberg&amp;nbsp;on the future of C#
- Michael Kennedy -&amp;nbsp;ubbuzz.com A custom Twitter watcher for .NET&amp;nbsp;developers

- Jamie and Long start the Channel 9 Task Force&amp;nbsp;for bugs and suggestions
- 1 week left for Show Off Contest
- Vincent Rithner -&amp;nbsp;Sobees, A free WPF Social Desktop Aggregator, Beta now available
- Rob Relyea -&amp;nbsp;XAML State of the Union
-&amp;nbsp;Caliburn Application Framework for WPF and Silverlight(via
Alvin Ashcraft)
- Tess Ferrandez -&amp;nbsp;5-part series on building a Silverlight Game
-&amp;nbsp;Live FrameIt SDK - Picasa and Photobucket integration
- Martin&#39;s pick of the week: 
Send a VSTS Pep Talk to your teammates
- Brian&#39;s pick of the week: 
Scott Hanselman&#39;s analysis of Quake Live, it isn&#39;t a Web game
- Dan&#39;s pick of the week:&amp;nbsp;Brian Peek&#39;s tip on how to force a 64-bit exe that uses a 32-bit dependencies to load the
32-bit CLR. 



</itunes:summary>
      <itunes:duration>1504</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/This-Week-Martin-Woodward-MVP-Summit-Web-Perf-Show-Off-and-a-VSTS-Pep-Talk</link>
      <pubDate>Sat, 07 Mar 2009 18:45:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/This-Week-Martin-Woodward-MVP-Summit-Web-Perf-Show-Off-and-a-VSTS-Pep-Talk</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/460102_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/460102_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_large_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_small_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_2MB_ch9.wmv" expression="full" duration="1504" fileSize="423710969" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_ch9.mp3" expression="full" duration="1504" fileSize="12034217" type="audio/mp3" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_ch9.mp4" expression="full" duration="1504" fileSize="148553795" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_ch9.wma" expression="full" duration="1504" fileSize="24346399" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_ch9.wmv" expression="full" duration="1504" fileSize="91038465" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_Zune_ch9.wmv" expression="full" duration="1504" fileSize="118798445" type="video/x-ms-wmv" medium="video"/>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_s_ch9.wmv" expression="full" duration="1504" fileSize="208" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/0/1/0/6/4/ThisWeekC9Mar6_ch9.wmv" length="91038465" type="video/x-ms-wmv"/>
      <dc:creator>Dan Fernandez</dc:creator>
      <itunes:author>Dan Fernandez</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/This-Week-Martin-Woodward-MVP-Summit-Web-Perf-Show-Off-and-a-VSTS-Pep-Talk/RSS</wfw:commentRss>
      <category>Live FrameIt</category>
      <category>MVP</category>
      <category>performance</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Silverlight 2 and the Louis Vuitton Pacific Series</title>
      <description><![CDATA[It is not everyday that the best sailors on the planet set up shop 150 metres from your work and race each other over a two week period but that is exactly what is happening for me right now.<br>
<br>
Check out <a shape="rect" href="http://lvps09.com" shape="rect">http://lvps09.com</a> and watch this screencast to learn more . A few things in the end made this application very flexible and extended my experiences with building production code in Silverlight
 2. This screencast gets into the nitty gritty details of this project... more details at
<a shape="rect" href="http://blogs.msdn.com/nigel/archive/2009/02/03/louis-vuitton-pacific-series-2009-auckland-new-zealand-the-silverlight-story.aspx" shape="rect">
http://blogs.msdn.com/nigel/archive/2009/02/03/louis-vuitton-pacific-series-2009-auckland-new-zealand-the-silverlight-story.aspx</a>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:163dcef307de425a85d99deb016ca014">]]></description>
      <comments>http://channel9.msdn.com/Blogs/Jafa/Silverlight-2-and-the-Louis-Vuitton-Pacific-Series</comments>
      <itunes:summary>It is not everyday that the best sailors on the planet set up shop 150 metres from your work and race each other over a two week period but that is exactly what is happening for me right now.

Check out http://lvps09.com and watch this screencast to learn more . A few things in the end made this application very flexible and extended my experiences with building production code in Silverlight
 2. This screencast gets into the nitty gritty details of this project... more details at

http://blogs.msdn.com/nigel/archive/2009/02/03/louis-vuitton-pacific-series-2009-auckland-new-zealand-the-silverlight-story.aspx
</itunes:summary>
      <itunes:duration>1701</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/Jafa/Silverlight-2-and-the-Louis-Vuitton-Pacific-Series</link>
      <pubDate>Fri, 13 Feb 2009 11:40:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/Jafa/Silverlight-2-and-the-Louis-Vuitton-Pacific-Series</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/457308_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/457308_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/af5eadbf-da0c-47ef-ab41-bfb3920c1bd0.jpg" height="384" width="512"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/38383d1c-aea8-497a-bee8-3f4dffb8af64.jpg" height="64" width="85"/>
      <media:group>
        <media:content url="http://mediadl.microsoft.com/mediadl/www/n/nz/lvps/LVPS09.wmv" expression="full" duration="1701" fileSize="109279409" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mediadl.microsoft.com/mediadl/www/n/nz/lvps/LVPS09.wmv" length="109279409" type="video/x-ms-wmv"/>
      <dc:creator>Nigel</dc:creator>
      <itunes:author>Nigel</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/Jafa/Silverlight-2-and-the-Louis-Vuitton-Pacific-Series/RSS</wfw:commentRss>
      <category>Deep Zoom</category>
      <category>Expression</category>
      <category>Expression Blend</category>
      <category>Expression Encoder</category>
      <category>Silverlight</category>
      <category>Silverlight 2</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Custom Slider for Silverlight 2 Media Players available for download</title>
      <description><![CDATA[ <p>Sorry it's taken so long, but we've now got the <a shape="rect" href="http://on10.net/blogs/benwagg/New-Custom-Slider-for-Silverlight-2-media-players/" shape="rect">Custom Slider for Silverlight 2 Media Players</a> up on MSDN.</p><p>Unlike the snippits I included earlier, this is a full project that can be modified. It’s being made available under the <a shape="rect" href="http://msdn.microsoft.com/en-us/library/cc512463.aspx" shape="rect">Microsoft Public License</a>.</p><p><a shape="rect" href="http://code.msdn.microsoft.com/SL2MediaSlider" shape="rect">Code Gallery Page</a><br><a shape="rect" href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=SL2MediaSlider&amp;DownloadId=3912 " shape="rect">Project Download</a></p><p>Enjoy!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:bd0cbd11a85a4bc1901b9e1000b17281">]]></description>
      <comments>http://channel9.msdn.com/Blogs/benwagg/Custom-Slider-for-Silverlight-2-Media-Players-available-for-download</comments>
      <itunes:summary> Sorry it&#39;s taken so long, but we&#39;ve now got the Custom Slider for Silverlight 2 Media Players up on MSDN.Unlike the snippits I included earlier, this is a full project that can be modified. It’s being made available under the Microsoft Public License.Code Gallery PageProject DownloadEnjoy!</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/benwagg/Custom-Slider-for-Silverlight-2-Media-Players-available-for-download</link>
      <pubDate>Wed, 26 Nov 2008 01:03:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/benwagg/Custom-Slider-for-Silverlight-2-Media-Players-available-for-download</guid>      
      <dc:creator>Ben Waggoner</dc:creator>
      <itunes:author>Ben Waggoner</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/benwagg/Custom-Slider-for-Silverlight-2-Media-Players-available-for-download/RSS</wfw:commentRss>
      <category>C#</category>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Microsoft .NET Framework: Declarative Programming Using XAML</title>
      <description><![CDATA[If you're using Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), or Windows Workflow Foundation (WF), then XAML is your new best friend! Learn how an entire application-from presentation to data to services to workflow--can
 be authored using simple, declarative XAML notations introduced in the next version of the .NET Framework. Learn about XAML additions like: support for generics, object references, non-default constructors, and more.
<ul class="speakers">
<li>
<div class="name">Daniel Roth</div>
<div class="description">Daniel Roth has been working on the Windows Communication Foundation and Windows Workflow Foundation for the past four years. He is excited to bring the benefits XAML to the world of webservices and workflows.</div>
</li><li>
<div class="name">Rob Relyea</div>
<div class="description"></div>
</li></ul>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c0f2aa119e2942c4b6019deb00189d6f">]]></description>
      <comments>http://channel9.msdn.com/Blogs/pdc2008/TL36</comments>
      <itunes:summary>If you&#39;re using Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), or Windows Workflow Foundation (WF), then XAML is your new best friend! Learn how an entire application-from presentation to data to services to workflow--can
 be authored using simple, declarative XAML notations introduced in the next version of the .NET Framework. Learn about XAML additions like: support for generics, object references, non-default constructors, and more.


Daniel Roth
Daniel Roth has been working on the Windows Communication Foundation and Windows Workflow Foundation for the past four years. He is excited to bring the benefits XAML to the world of webservices and workflows.

Rob Relyea


</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/pdc2008/TL36</link>
      <pubDate>Wed, 29 Oct 2008 16:38:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/pdc2008/TL36</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/426753_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/426753_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/pdc08/THUMBNAILS/TL36.jpg" height="240" width="320"/>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/dpe/C9_viewSession.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/pdc08/MP4/TL36.mp4" expression="full" fileSize="67618716" type="video/mp4" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV/TL36.wmv" expression="full" fileSize="118149795" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/TL36.wmv" expression="full" fileSize="247085999" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/pdc08/ZUNE/TL36.wmv" expression="full" fileSize="46289135" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV/TL36.wmv" length="118149795" type="video/x-ms-wmv"/>
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/pdc2008/TL36/RSS</wfw:commentRss>
      <category>.NET</category>
      <category>.NET Framework</category>
      <category>Advanced</category>
      <category>Breakout Session</category>
      <category>WCF</category>
      <category>WF</category>
      <category>WPF</category>
      <category>XAML</category>
    </item>
  <item>
      <title>New Custom Slider for Silverlight 2 media players</title>
      <description><![CDATA[ <p>My Silverlight teammates Akshay Johar and Andre Michaud have built a new custom slider for use in Silverlight 2 media players.</p><p>When you scrub the default slider in a MediaElement today, it generates a whole slew of valueChanged events, resulting in a huge number of seeks per second. This can confuse media playback, particularly when streaming from Windows Media Services, which then gets flooded with many requests a second.</p><p>Essentially it detects a “crazy mode” scrub, and quietly ignores it while the “crazy mode” is in place. Once out of this mode, it happily sends and receives a successful seek.</p><p>So, the player only fires ValueChanged on mouse up (on the slider thumb or the slider tracker), or the final seek request of a cluster that comes in at once.</p><p>It’s also uses Tim Heuer’s <a shape="rect" href="http://timheuer.com/blog/archive/2008/09/08/customizing-slider-enable-move-mouse-to-point.aspx" target="_blank" shape="rect">absolute value slider</a>.</p><p>Now, let me try this new <a shape="rect" href="http://get.live.com/writer/overview" target="_blank" shape="rect">Windows Live Writer</a> plug-in for <a shape="rect" href="http://gallery.live.com/liveItemDetail.aspx?li=1f57bd9b-a692-4593-9e9e-e2962d9c0eee&amp;bt=9&amp;pl=8" target="_blank" shape="rect">Insert Code Snippet</a> for the C# code.<br><br><strong>(EDIT)</strong> A sample project is also now <a shape="rect" href="http://http://on10.net/blogs/benwagg/Custom-Slider-for-Silverlight-2-Media-Players-available-for-download/" shape="rect">available for download</a>.</p><div><div><pre><span> 1:</span> <span>using</span> System;</pre><pre><span> 2:</span> <span>using</span> System.Net;</pre><pre><span> 3:</span> <span>using</span> System.Windows;</pre><pre><span> 4:</span> <span>using</span> System.Windows.Controls;</pre><pre><span> 5:</span> <span>using</span> System.Windows.Documents;</pre><pre><span> 6:</span> <span>using</span> System.Windows.Ink;</pre><pre><span> 7:</span> <span>using</span> System.Windows.Input;</pre><pre><span> 8:</span> <span>using</span> System.Windows.Media;</pre><pre><span> 9:</span> <span>using</span> System.Windows.Media.Animation;</pre><pre><span> 10:</span> <span>using</span> System.Windows.Shapes;</pre><pre><span> 11:</span> <span>using</span> System.Windows.Controls.Primitives;</pre><pre><span> 12:</span> <span>using</span> System.Windows.Threading;</pre><pre><span> 13:</span>&nbsp; </pre><pre><span> 14:</span> <span>namespace</span> VirtualizedSlider</pre><pre><span> 15:</span> {</pre><pre><span> 16:</span>     <span>public</span> <span>class</span> CustomSlider : Slider</pre><pre><span> 17:</span>     {</pre><pre><span> 18:</span>         <span>public</span> Thumb horizontalThumb;</pre><pre><span> 19:</span>         <span>private</span> FrameworkElement horizontalLeftTrack;</pre><pre><span> 20:</span>         <span>private</span> FrameworkElement horizontalRightTrack;</pre><pre><span> 21:</span>         <span>private</span> <span>double</span> oldValue = 0, newValue = 0, prevNewValue = 0;</pre><pre><span> 22:</span>         <span>public</span> <span>event</span> RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt; MyValueChanged;</pre><pre><span> 23:</span>         <span>public</span> <span>event</span> RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt; MyValueChangedInDrag;</pre><pre><span> 24:</span>         </pre><pre><span> 25:</span>         <span>private</span> DispatcherTimer dragtimer = <span>new</span> DispatcherTimer();</pre><pre><span> 26:</span>         <span>private</span> <span>double</span> dragTimeElapsed = 0;</pre><pre><span> 27:</span>         <span>private</span> <span>const</span> <span>short</span> DragWaitThreshold = 200, DragWaitInterval = 100;</pre><pre><span> 28:</span>         <span>public</span> Rectangle progressRect = <span>null</span>;</pre><pre><span> 29:</span>         <span>private</span> <span>bool</span> dragSeekJustFired = <span>false</span>;</pre><pre><span> 30:</span>&nbsp; </pre><pre><span> 31:</span>         <span>public</span> CustomSlider()</pre><pre><span> 32:</span>         {</pre><pre><span> 33:</span>             <span>this</span>.ValueChanged &#43;= <span>new</span> RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt;(CustomSlider_ValueChanged);</pre><pre><span> 34:</span>             dragtimer.Interval = <span>new</span> TimeSpan(0, 0, 0, 0, DragWaitInterval);</pre><pre><span> 35:</span>             dragtimer.Tick &#43;= <span>new</span> EventHandler(dragtimer_Tick);</pre><pre><span> 36:</span>             </pre><pre><span> 37:</span>         }</pre><pre><span> 38:</span>&nbsp; </pre><pre><span> 39:</span>         <span>void</span> dragtimer_Tick(<span>object</span> sender, EventArgs e)</pre><pre><span> 40:</span>         {</pre><pre><span> 41:</span>             dragTimeElapsed &#43;= DragWaitInterval;</pre><pre><span> 42:</span>             <span>if</span> (dragTimeElapsed &gt;= DragWaitThreshold)</pre><pre><span> 43:</span>             {</pre><pre><span> 44:</span>                 RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt; handler = MyValueChangedInDrag;</pre><pre><span> 45:</span>                 <span>if</span> ((handler != <span>null</span>) &amp;&amp; (newValue != prevNewValue))</pre><pre><span> 46:</span>                 {</pre><pre><span> 47:</span>                     handler(<span>this</span>, <span>new</span> RoutedPropertyChangedEventArgs&lt;<span>double</span>&gt;(oldValue, newValue));</pre><pre><span> 48:</span>                     dragSeekJustFired = <span>true</span>;</pre><pre><span> 49:</span>                     prevNewValue = newValue;</pre><pre><span> 50:</span>                 }</pre><pre><span> 51:</span>                 dragTimeElapsed = 0;</pre><pre><span> 52:</span>             }</pre><pre><span> 53:</span>         }</pre><pre><span> 54:</span>&nbsp; </pre><pre><span> 55:</span>         <span>void</span> CustomSlider_ValueChanged(<span>object</span> sender, RoutedPropertyChangedEventArgs&lt;<span>double</span>&gt; e)</pre><pre><span> 56:</span>         {</pre><pre><span> 57:</span>             oldValue = e.OldValue;</pre><pre><span> 58:</span>             newValue = e.NewValue;</pre><pre><span> 59:</span>             <span>if</span> (horizontalThumb.IsDragging)</pre><pre><span> 60:</span>             {</pre><pre><span> 61:</span>                 dragTimeElapsed = 0;</pre><pre><span> 62:</span>                 dragtimer.Stop();</pre><pre><span> 63:</span>                 dragtimer.Start();</pre><pre><span> 64:</span>                 dragSeekJustFired = <span>false</span>;</pre><pre><span> 65:</span>             }</pre><pre><span> 66:</span>         }</pre><pre><span> 67:</span>&nbsp; </pre><pre><span> 68:</span>         <span>public</span> <span>override</span> <span>void</span> OnApplyTemplate()</pre><pre><span> 69:</span>         {</pre><pre><span> 70:</span>             <span>base</span>.OnApplyTemplate();</pre><pre><span> 71:</span>&nbsp; </pre><pre><span> 72:</span>             horizontalThumb = GetTemplateChild(<span>&quot;HorizontalThumb&quot;</span>) <span>as</span> Thumb;</pre><pre><span> 73:</span>&nbsp; </pre><pre><span> 74:</span>             horizontalLeftTrack = GetTemplateChild(<span>&quot;LeftTrack&quot;</span>) <span>as</span> FrameworkElement;</pre><pre><span> 75:</span>             horizontalRightTrack = GetTemplateChild(<span>&quot;RightTrack&quot;</span>) <span>as</span> FrameworkElement;</pre><pre><span> 76:</span>             progressRect = GetTemplateChild(<span>&quot;progressRect&quot;</span>) <span>as</span> Rectangle;</pre><pre><span> 77:</span>&nbsp; </pre><pre><span> 78:</span>             <span>if</span> (horizontalLeftTrack != <span>null</span>) horizontalLeftTrack.MouseLeftButtonDown &#43;= <span>new</span> MouseButtonEventHandler(OnMoveThumbToMouse);</pre><pre><span> 79:</span>             <span>if</span> (horizontalRightTrack != <span>null</span>) horizontalRightTrack.MouseLeftButtonDown &#43;= <span>new</span> MouseButtonEventHandler(OnMoveThumbToMouse);</pre><pre><span> 80:</span>&nbsp; </pre><pre><span> 81:</span>             horizontalThumb.DragCompleted &#43;= <span>new</span> DragCompletedEventHandler(DragCompleted);</pre><pre><span> 82:</span>             progressRect.Width = <span>this</span>.Width;            </pre><pre><span> 83:</span>         }</pre><pre><span> 84:</span>&nbsp; </pre><pre><span> 85:</span>         <span>private</span> <span>void</span> OnMoveThumbToMouse(<span>object</span> sender, MouseButtonEventArgs e)</pre><pre><span> 86:</span>         {</pre><pre><span> 87:</span>             e.Handled = <span>true</span>;</pre><pre><span> 88:</span>             Point p = e.GetPosition(<span>this</span>);</pre><pre><span> 89:</span>&nbsp; </pre><pre><span> 90:</span>             <span>if</span> (<span>this</span>.Orientation == Orientation.Horizontal)</pre><pre><span> 91:</span>             {</pre><pre><span> 92:</span>                 Value = (p.X - (horizontalThumb.ActualWidth / 2)) / (ActualWidth - horizontalThumb.ActualWidth) * Maximum;</pre><pre><span> 93:</span>             }</pre><pre><span> 94:</span>             RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt; handler = MyValueChanged;</pre><pre><span> 95:</span>             <span>if</span> (handler != <span>null</span>)</pre><pre><span> 96:</span>             {</pre><pre><span> 97:</span>                 handler(<span>this</span>, <span>new</span> RoutedPropertyChangedEventArgs&lt;<span>double</span>&gt;(oldValue, Value));</pre><pre><span> 98:</span>             }</pre><pre><span> 99:</span>         }</pre><pre><span> 100:</span>&nbsp; </pre><pre><span> 101:</span>         <span>private</span> <span>void</span> DragCompleted(<span>object</span> sender, DragCompletedEventArgs e)</pre><pre><span> 102:</span>         {</pre><pre><span> 103:</span>             dragtimer.Stop();</pre><pre><span> 104:</span>             dragTimeElapsed = 0;</pre><pre><span> 105:</span>             RoutedPropertyChangedEventHandler&lt;<span>double</span>&gt; handler = MyValueChanged;</pre><pre><span> 106:</span>             <span>if</span> ((handler != <span>null</span>) &amp;&amp; (!dragSeekJustFired))</pre><pre><span> 107:</span>             {</pre><pre><span> 108:</span>                 handler(<span>this</span>, <span>new</span> RoutedPropertyChangedEventArgs&lt;<span>double</span>&gt;(oldValue, <span>this</span>.Value));</pre><pre><span> 109:</span>             }</pre><pre><span> 110:</span>         }</pre><pre><span> 111:</span>     }</pre><pre><span> 112:</span> }</pre></div></div><p>&nbsp;</p><p>And here’s the XAML from the progressSliderStyle, demonstrating how the custom slider knows about mouse clicks on the track (the “LeftTrack” and “RightTrack” rectangles inserted in the template handle this):</p><div><div><pre><span> 1:</span> &lt;Setter Property=<span>&quot;Template&quot;</span>&gt;</pre><pre><span> 2:</span>                  &lt;Setter.Value&gt;</pre><pre><span> 3:</span>                      &lt;ControlTemplate TargetType=<span>&quot;Slider&quot;</span>&gt;</pre><pre><span> 4:</span>                          &lt;Grid x:Name=<span>&quot;Root&quot;</span>&gt;</pre><pre><span> 5:</span>                              &lt;Grid.Resources&gt;</pre><pre><span> 6:</span>                                  &lt;ControlTemplate x:Key=<span>&quot;RepeatButtonTemplate&quot;</span>&gt;</pre><pre><span> 7:</span>                                      &lt;Grid x:Name=<span>&quot;Root&quot;</span> Opacity=<span>&quot;0&quot;</span> Background=<span>&quot;Transparent&quot;</span>/&gt;</pre><pre><span> 8:</span>                                  &lt;/ControlTemplate&gt;</pre><pre><span> 9:</span>                              &lt;/Grid.Resources&gt;</pre><pre><span> 10:</span>                              &lt;vsm:VisualStateManager.VisualStateGroups&gt;</pre><pre><span> 11:</span>                                  &lt;vsm:VisualStateGroup x:Name=<span>&quot;CommonStates&quot;</span>&gt;</pre><pre><span> 12:</span>                                      &lt;vsm:VisualState x:Name=<span>&quot;Normal&quot;</span>/&gt;</pre><pre><span> 13:</span>                                      &lt;vsm:VisualState x:Name=<span>&quot;MouseOver&quot;</span>/&gt;</pre><pre><span> 14:</span>                                      &lt;vsm:VisualState x:Name=<span>&quot;Disabled&quot;</span>&gt;</pre><pre><span> 15:</span>                                          &lt;Storyboard&gt;</pre><pre><span> 16:</span>                                              &lt;DoubleAnimation Storyboard.TargetName=<span>&quot;Root&quot;</span> Storyboard.TargetProperty=<span>&quot;(UIElement.Opacity)&quot;</span> To=<span>&quot;0.5&quot;</span>/&gt;</pre><pre><span> 17:</span>                                          &lt;/Storyboard&gt;</pre><pre><span> 18:</span>                                      &lt;/vsm:VisualState&gt;</pre><pre><span> 19:</span>                                  &lt;/vsm:VisualStateGroup&gt;</pre><pre><span> 20:</span>                              &lt;/vsm:VisualStateManager.VisualStateGroups&gt;</pre><pre><span> 21:</span>&nbsp; </pre><pre><span> 22:</span>                              &lt;!-- Horizontal Template --&gt;</pre><pre><span> 23:</span>                              &lt;Grid x:Name=<span>&quot;HorizontalTemplate&quot;</span> Background=<span>&quot;{TemplateBinding Background}&quot;</span>&gt;</pre><pre><span> 24:</span>                                  &lt;Grid.ColumnDefinitions&gt;</pre><pre><span> 25:</span>                                      &lt;ColumnDefinition Width=<span>&quot;Auto&quot;</span>/&gt;</pre><pre><span> 26:</span>                                      &lt;ColumnDefinition Width=<span>&quot;Auto&quot;</span>/&gt;</pre><pre><span> 27:</span>                                      &lt;ColumnDefinition Width=<span>&quot;*&quot;</span>/&gt;</pre><pre><span> 28:</span>                                  &lt;/Grid.ColumnDefinitions&gt;</pre><pre><span> 29:</span>&nbsp; </pre><pre><span> 30:</span>                                  &lt;!-- Track Layer --&gt;</pre><pre><span> 31:</span>                                  &lt;Rectangle x:Name=<span>&quot;progressRect&quot;</span> Stroke=<span>&quot;#FFA3AEB9&quot;</span> StrokeThickness=<span>&quot;{TemplateBinding BorderThickness}&quot;</span> Fill=<span>&quot;Red&quot;</span> Grid.Column=<span>&quot;0&quot;</span> Grid.ColumnSpan=<span>&quot;3&quot;</span> Height=<span>&quot;3&quot;</span> Width=<span>&quot;5&quot;</span> RadiusX=<span>&quot;1&quot;</span> RadiusY=<span>&quot;1&quot;</span> Margin=<span>&quot;5,0,5,0&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span> Visibility=<span>&quot;Collapsed&quot;</span> HorizontalAlignment=<span>&quot;Left&quot;</span> /&gt;</pre><pre><span> 32:</span>                                  &lt;Rectangle Stroke=<span>&quot;#FFA3AEB9&quot;</span> StrokeThickness=<span>&quot;{TemplateBinding BorderThickness}&quot;</span> Fill=<span>&quot;#FFE6EFF7&quot;</span> Grid.Column=<span>&quot;0&quot;</span> Grid.ColumnSpan=<span>&quot;3&quot;</span> Height=<span>&quot;3&quot;</span> RadiusX=<span>&quot;1&quot;</span> RadiusY=<span>&quot;1&quot;</span> Margin=<span>&quot;5,0,5,0&quot;</span>  Canvas.ZIndex=<span>&quot;0&quot;</span> /&gt;</pre><pre><span> 33:</span>&nbsp; </pre><pre><span> 34:</span>                                  &lt;!-- Repeat Buttons &#43; Thumb --&gt;</pre><pre><span> 35:</span>                                  &lt;RepeatButton x:Name=<span>&quot;HorizontalTrackLargeChangeDecreaseRepeatButton&quot;</span> IsTabStop=<span>&quot;False&quot;</span> Template=<span>&quot;{StaticResource RepeatButtonTemplate}&quot;</span> Grid.Column=<span>&quot;0&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span>/&gt;</pre><pre><span> 36:</span>                                  &lt;Rectangle x:Name=<span>&quot;LeftTrack&quot;</span> Grid.Column=<span>&quot;0&quot;</span> Fill=<span>&quot;#00FFFFFF&quot;</span> Cursor=<span>&quot;Hand&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span>/&gt;</pre><pre><span> 37:</span>                                  &lt;Thumb Height=<span>&quot;18&quot;</span> x:Name=<span>&quot;HorizontalThumb&quot;</span> Width=<span>&quot;11&quot;</span> Grid.Column=<span>&quot;1&quot;</span> IsTabStop=<span>&quot;True&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span>/&gt;</pre><pre><span> 38:</span>                                  &lt;RepeatButton x:Name=<span>&quot;HorizontalTrackLargeChangeIncreaseRepeatButton&quot;</span> IsTabStop=<span>&quot;False&quot;</span> Template=<span>&quot;{StaticResource RepeatButtonTemplate}&quot;</span> Grid.Column=<span>&quot;2&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span>/&gt;</pre><pre><span> 39:</span>                                  &lt;Rectangle x:Name=<span>&quot;RightTrack&quot;</span> Grid.Column=<span>&quot;2&quot;</span> Fill=<span>&quot;#00FFFFFF&quot;</span> Cursor=<span>&quot;Hand&quot;</span> Canvas.ZIndex=<span>&quot;1&quot;</span>/&gt;</pre><pre><span> 40:</span>                              &lt;/Grid&gt;</pre><pre><span> 41:</span>                          &lt;/Grid&gt;</pre><pre><span> 42:</span>                      &lt;/ControlTemplate&gt;</pre><pre><span> 43:</span>                  &lt;/Setter.Value&gt;</pre><pre><span> 44:</span>              &lt;/Setter&gt;</pre></div></div> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/xaml/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d45bc086f27246459e2f9e1000b15f31">]]></description>
      <comments>http://channel9.msdn.com/Blogs/benwagg/New-Custom-Slider-for-Silverlight-2-media-players</comments>
      <itunes:summary> My Silverlight teammates Akshay Johar and Andre Michaud have built a new custom slider for use in Silverlight 2 media players.When you scrub the default slider in a MediaElement today, it generates a whole slew of valueChanged events, resulting in a huge number of seeks per second. This can confuse media playback, particularly when streaming from Windows Media Services, which then gets flooded with many requests a second.Essentially it detects a “crazy mode” scrub, and quietly ignores it while the “crazy mode” is in place. Once out of this mode, it happily sends and receives a successful seek.So, the player only fires ValueChanged on mouse up (on the slider thumb or the slider tracker), or the final seek request of a cluster that comes in at once.It’s also uses Tim Heuer’s absolute value slider.Now, let me try this new Windows Live Writer plug-in for Insert Code Snippet for the C# code.(EDIT) A sample project is also now available for download. 1: using System; 2: using System.Net; 3: using System.Windows; 4: using System.Windows.Controls; 5: using System.Windows.Documents; 6: using System.Windows.Ink; 7: using System.Windows.Input; 8: using System.Windows.Media; 9: using System.Windows.Media.Animation; 10: using System.Windows.Shapes; 11: using System.Windows.Controls.Primitives; 12: using System.Windows.Threading; 13:&amp;nbsp;  14: namespace VirtualizedSlider 15: { 16:     public class CustomSlider : Slider 17:     { 18:         public Thumb horizontalThumb; 19:         private FrameworkElement horizontalLeftTrack; 20:         private FrameworkElement horizontalRightTrack; 21:         private double oldValue = 0, newValue = 0, prevNewValue = 0; 22:         public event RoutedPropertyChangedEventHandler&amp;lt;double&amp;gt; MyValueChanged; 23:         public event RoutedPropertyChangedEventHandler&amp;lt;double&amp;gt; MyValueChangedInDrag; 24:          25:         private DispatcherTimer dragtimer = new DispatcherTimer(); 26:         private double dragTimeElapsed = 0; 27:        </itunes:summary>
      <link>http://channel9.msdn.com/Blogs/benwagg/New-Custom-Slider-for-Silverlight-2-media-players</link>
      <pubDate>Tue, 28 Oct 2008 22:13:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/benwagg/New-Custom-Slider-for-Silverlight-2-media-players</guid>      
      <dc:creator>Ben Waggoner</dc:creator>
      <itunes:author>Ben Waggoner</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/benwagg/New-Custom-Slider-for-Silverlight-2-media-players/RSS</wfw:commentRss>
      <category>C#</category>
      <category>Silverlight</category>
      <category>XAML</category>
    </item>    
</channel>
</rss>
