Silverlight, WPF and .NET Subscribe via RSS
Photo of Alan Cobb
About me:   I'm a Silverlight 2, WPF (Windows Presentation Foundation) and .NET programming consultant based in Northern California, USA.   See more about the Silverlight presentations I have been giving here.

I'm currently available for Silverlight or WPF contract work.  Send me an email at the address here and we can talk about your project.  (Principals only. No 3rd parties please).
Changing Silverlight properties dynamically with a "binding-relay" object
By: Alan Cobb Date: 2008-Jul-17 14:39

Motivation:
What if you want the user of your Silverlight app to be able to change some properties of your UI dynamically on-the-fly?  For example, it would be nice to let your user set the FontSize to their liking at runtime and have that new size used by all controls immediately.

One way to do that is with data binding and a shared "app-global" "binding-relay" object.  The graphic below shows the UI of this sample app and how its elements are indirectly connected with data binding via a "binding-relay" object.  This general technique has been described by other people as part of larger articles (see for example, here and here [both links are slow]), but here I want to emphasize just this one technique.  Although it has some disadvantages, it's a useful pattern to have in your toolbox.

My sample app is split into two sections.  The group of "controller" elements in the upper half is used to dynamically change the properties of the "controlled" TextBlocks in the lower half.  The graphic below shows the UI of this sample app and how its elements are indirectly connected with data binding.

Annotated screen capture of sample app demoing Silverlight data binding using a binding-relay object

Live copy of this sample app (SL2B2 version)

Sample source code as zipped VS2008 solution
(After you unzip and rebuild it, remember to again set the HTML page in the web project as the Start Page before you run it with F5.)

How it works:
We start by creating a custom class that exposes the global properties we want to support.  For example, "double dFontSize".  In this sample the class is called CBindingRelayClass_ApplicationWideSettings.  We create a single shared instance of that class by instantiating it in the App.Resources section of our App.xaml.  Now multiple elements anywhere in our application can bind their FontSize properties as targets to the dFontSize source property on the global object.  This class must support the INotifyPropertyChanged interface.  That's how the binding system is alerted when one of our global properties is changed.  Then the binding system "relays" that change out to all the bound targets of that global source property.  That's why I call it a "binding-relay" object.

We drive changes to the global dFontSize property with a Slider.  The Slider is TwoWay bound back to the global binding source object.  The binding mode for the Slider must be TwoWay in order for it to drive the value of the dFontSize property (changes flowing from target back to source).  Normal OneWay binding only moves changes in the other direction, from binding source to target.

So those are the basic "tricks" behind this technique.

More implementation details:
It's easy enough to use TwoWay binding to make the Slider drive a property like dFontSize because it has the simple type double.  But what about a type like FontFamily?  In this sample I use a ListBox to choose the FontFamily.  But instead of TwoWay binding, I fall back on an "old school" event handler.  In the ListBox.SelectionChanged event handler I "manually" instantiate a new FontFamily object based on the selected line in the ListBox and assign it to the oFontFamily property on the global "binding relay" object.

What about the Slider driving the oSolidColorBrush property on the global object?  There I also go "old school" rather than using TwoWay binding.  In the Slider.ValueChanged event handler I "manually" translate the Slider Value (which ranges from 0x000000 to 0xffffff) into an RGB color, use that to instantiate a new SolidColorBrush and finally assign that to the global oSolidColorBrush property.

In theory we could have used TwoWay binding to drive the values of both these more complex properties.  That would require writing value converter classes that implement IValueConverter.  For example, we should be able to write a value converter that translates back and forth between the types double and SolidColorBrush.  My preliminary experiments under SL2B2 with TwoWay binding using value converters for more complex types didn't work, so I haven't shown that here.

Disadvantages:
Although using a "binding-relay" object does let you dynamically change properties in real-time, it also has some disadvantages.  One burden is just that you need to define and instantiate the binding-relay object somewhere.  In contrast to the current Silverlight version, WPF's binding system allows you to directly bind one element to another, without needing a "relay" object in between (See for example).  So in WPF you could directly bind the FontSize property of one element to the output of a Slider control.  Another drawback is the extra binding XAML you must add to every control that consumes the "dynamic property".   For example:  FontSize="{Binding dFontSize}".

New "property value inheritance" of font properties in Silverlight:
This technique's ability to dynamically control the font properties of many target elements simultaneously seemed a bit more impressive before SL2 Beta 2.  But now SL2B2 has introduced more "property value inheritance" to Silverlight, something which WPF already broadly supports.  Most of the font-related properties (like FontSize and FontFamily) have been moved to the Control class in SL2B2.  Now those values are "inherited" by the child elements inside a given control.  This means you can set the FontSize and FontFamily once on a UserControl and those values will cascade (like in CSS) down to the child elements.  To demonstrate that you can add these bound properties to the XAML that defines the Page UserControl:

    FontSize="{Binding dFontSize}"
    FontFamily="{Binding oFontFamily}"

After that change when you vary the FontSize Slider, the text size changes everywhere on the Page, not just in the lower half.  We are still using the "binding-relay" object, but now it is unnecessary to duplicate the same binding XAML on every target element.

Alan Cobb

Comments [2]  |  #  
How to debug Silverlight 2 cross-domain problems with Fiddler
By: Alan Cobb Date: 2008-Mar-26 15:23

A great tool for debugging Silverlight 2 cross-domain problems is the free "debugging proxy" tool called Fiddler.  Fiddler acts like an "HTTP sniffer".  It lets you watch as your browser has HTTP-conversations with servers.  This post is a very brief example of using Fiddler to "spy" on Silverlight 2 as it looks for cross-domain policy files.  For the demo I'm using ScottGu's Silverlight 2 Digg client demo.  Scott now has downloadable Silverlight 2 sources for his demo here. (I did a translation to WPF in a previous blog article.)

If you download and build Scott's SL2 demo and have Fiddler installed, you should be able to capture a "trace" of the HTTP requests made by Silverlight to the Digg site, and the responses.  In the attached screen capture of Fiddler you can see Silverlight first try to open clientaccesspolicy.xml from Digg's site and fail, but then try and succeed to open crossdomain.xml.  You can also see the contents of crossdomain.xml that were returned.  The '*' is allowing any domain to call Digg's APIs.

When it comes to testing some unknown site to see if it has cross-domain policy files, one technique is to just hit that domain with your browser and see if it can find those files.  For example, if you type this URI into the browser: http://services.digg.com/crossdomain.xml, the browser will successfully find it and show you its contents.  So their "welcome" sign has been lit.

Alan Cobb

Comments [0]  |  #  
SD-West-2008 PPT Slides for My "Introduction to Silverlight" Presentation
By: Alan Cobb Date: 2008-Mar-06 19:14

I'm doing an "Introduction to Silverlight" presentation tomorrow (2008-Mar-07) at SD-West-2008 in Santa Clara, California focusing on the .NET based Silverlight 2.

Here are my PowerPoint slides (5.3MB).

Alan Cobb

Comments [2]  |  Silverlight #  
Translating ScottGu’s Silverlight “Digg Client” to WPF
By: Alan Cobb Date: 2008-Feb-26 15:01

As Jesse Liberty has suggested, since the Silverlight 2 beta has not yet been released I decided to do a WPF implementation of ScottGu’s excellent Silverlight 2 “Digg client” tutorial (thanks Scott!).  It turned out to be a bit harder than I expected, but I did learn things.  Below I list the changes I had to make to translate Scott’s Silverlight 2 app to WPF.  Scott already lists some of these in step 8 of his tutorial.

 

You can download my working WPF VS-2008 solution here.

 

Converting to a WPF “Navigation App”:

To create a browser-like experience similar to Silverlight I wrote my version as a WPF “navigation app”.  Another way would be as an XBAP, but since Scott used a full WPF desktop app, so did I.  To make it a WPF “navigation app” I had to replace Scott’s outer Window with a NavigationWindow.  Scott’s original Silverlight UserControl subclass has the name Page, but WPF already has a general Page class used by navigation apps.  Therefore I replaced his UserControl base class with a WPF Page base class, and named the derived class Page1.

 

 

 

Emulating Silverlight 2’s HyperlinkButton:

Since WPF does not have an exact equivalent of Silverlight 2’s HyperlinkButton class, Scott replaces it with a TextBlock.  I’m not sure if Scott wrote the extra WPF code to do it, but I decided to make the TextBlock actually behave like a “hyperlink”.  Therefore when clicked it must actually navigate to the target HTML page, and it must expose bindable dependency properties (DPs) that emulate HyperlinkButton’s DPs.  I ended up creating a UserControl called HyperlinkButton_ForWPF to encapsulate this functionality and wrap the TextBlock. 

 

To support data binding I needed to add two custom DPs to HyperlinkButton_ForWPF: Content2 and NavigateUri.  Why call it Content2 and not Content like Silverlight does?  Because UserControl already has a DP named Content.  There might be a way to “repurpose” the UserControl.Content DP, but the things I tried didn’t work, so I just added the custom Content2 DP instead.

 

Once the HyperlinkButton_ForWPF was working, I was able to click on the title text for an individual Digg HTML article and have the outer NavigationWindow get filled with that HTML page.  Initially pressing the back button did return me to the original Page, but all the existing Digg content was gone.  That is the default behavior of a WPF navigation app.  It recreates each page from scratch whenever it is reentered.   But we want the state of the Page saved, so that we don’t need to requery Digg each time.  By setting Page.KeepAlive to true, we get the desired state-retaining behavior.

 

 

  

 

Calling the Digg Web API:

Scott uses a WebClient object to query the Digg web API.  I needed to make several changes before it would work correctly under WPF.  The original version returned HTTP error code 403 in response to my queries.  Digg’s documentation says that our HTTP query request must include a User-Agent HTTP Header.  Adding that fixed the 403 errors.  Another problem was that apostrophes in stories were displayed with strange characters.  The fix for that was to explicitly tell the WebClient object to assume UTF-8 encoding.

 

I modified Scott’s original Digg query a little also.  Instead of just requesting 20 random stories from a given topic (/stories/topic/{topic name}), I used a different endpoint (/stories/topic/{topic name}/popular).  The added  “popular” part asks for the most popular stories.  I also added a “sort” parameter, so the most popular stories are at the top of the list.  By the way, there are only about 50 “topics” that this endpoint queries for, so don’t expect to be able to put any arbitrary phrase in the search box (as if it were Google).  The list of topics is here: http://apidoc.digg.com/Topics.  For example, “basketball”, “microsoft” or “music”.

 

What was my conclusion from all this?  That it will be great when we actually get the real Silverlight 2 beta to play with, rather than trying to approximate it :).

Alan Cobb

Comments [9]  |  Silverlight | WPF #  
A more debuggable Silverlight.js :
By: Alan Cobb Date: 2007-Oct-20 19:40

The main point of this article is to make my reformatted, more debuggable version of Silverlight available to other people for download:

      For 2007-09 v1.0 SDK:  Silverlight_DebugPretty_V10.js 
      For 2007-09 v1.1 SDK:  Silverlight_DebugPretty_V11.js

Background and explanation:
As you probably know, Silverlight.js is a helper file that all Silverlight applications are required to use when starting up.  To make it download faster it has been "minified" into a single line of JavaScript 7000+ characters long.  That's OK for production use, but it makes the source code unusable for debugging.  For debugging you want to be able to use Visual Studio to single step through readable, understandable source code and look at variable values and stack traces.


The 2007-07 version of the Silverlight SDK included such a reformatted Silverlight.js (even including some descriptive comments [gasp!]), but I couldn't find one in the 2007-09 versions of the SDK.  So I made the ones linked to above. 

To do the reformatting ("pretty printing") I started with a free trial copy of the commercial Polystyle code-reformatter product.  That turned the single JavaScript line into about 400 readable lines, with proper indenting.  I followed that with a little hand editing to visually separate the individual methods with lines of asterisks.  One could go even further and add some descriptive comments.

Once you are a old hand at JavaScript and Silverlight you probably won't spend much time looking at Silverlight.js.  But if you are like me, with a background in C# and C++ you may initially find JavaScript's behavior somewhat "odd" and mysterious.  It can be instructive to single step through the startup code in Silverlight.js.  See how one of the first steps is to "instantiate" all the methods of the Silverlight object so they can be called later?

Minification and obfuscation:
I found out via petemounce on the Silverlight Forum (see: http://silverlight.net/forums/t/5697.aspx) that there are tools available specifically for the task of minimizing the size of ("minifying") your JavaScript or HTML.  See: http://www.julienlecomte.net/blog/2007/08/13/introducing-the-yui-compressor/

This is closely related to the task of obfuscation, in which you try to make your code harder to reverse engineer.  Deliberately debugger-unfriendly.  See: http://yuiblog.com/blog/2006/03/06/minification-v-obfuscation/

Comments [5]  |  Silverlight | debugging #  
First entry for Alan Cobb's new blog (Done 2007-10-03)
By: Alan Cobb Date: 2007-Oct-03 11:56

Hi,

This is my new blog.  Interesting Silverlight, WPF and .NET technical content to follow...

Regarding how this blog was designed and implemented:
My visual design priorities for this site's HTML/CSS were a liquid layout and good tolerance of text resizing.  Similar to http://news.google.com.

As the footer shows, this blog is currently implemented with dasBlog 2.x running on ASP.NET 2.0.  I'm currently hosted on GoDaddy and happy with them.  To get the visual look and liquid resizing behavior I wanted, I needed to modify some of dasBlog's ASP.NET C# code as well as the page templates and CSS.

Alan Cobb

Comments [0]  |  dasBlog #  
Copyright 2008 Alan Cobb:  www.alancobb.com    Subscribe: Subscribe via RSS
Theme by Alan Cobb, based on dasBlog calmBlue.
newtelligence dasBlog 2.0.7180.0
Page rendered: 2008-Jul-25 10:11 CA, USA Time
dasBlog logo
Search
Admin Login