Best Quote From Build Tuesday, September 13 2011 on Blog
“...all of your knowledge around XAML, around C#, around Silverlight and all that stuff, it just carries straight across to here [Windows 8] ...”
“...all of your knowledge around XAML, around C#, around Silverlight and all that stuff, it just carries straight across to here [Windows 8] ...”
Silverlight projects I’ve been a part of tend to develop a robust set of converters. Anything I can do to keep my view model in a relatively pure state (see Part 0 for more details) keeps me happy. However there are times when I also don’t want to write a converter for one simple “throw-away” data conversion. I know I’m not likely to reuse this and I know I also don’t want to change my view model for this one conversion either. Instead, I’ve been using a simple “Code behind converter” where you can specify your conversion code in the code behind of your view.
This converter simply provides a Convert and ConvertBack event that can be handled on the code behind.
For an example of it in use, here is a business entity (which has a status enumeration):
And here is a view model for a business view:
And here is the view that displays a friendly version of the status enumeration:
And here is the view’s code behind:
If it turns out you need this elsewhere, it’s easy to change this into its own converter because you followed the same approach as you would have when needing a converter in the first place. Move the code into a custom IValueConverter class and update your usages of this to your new converter.
Happened upon a Silverlight bug today. In essence, if you have a ComboBox with its SelectedValue bound to a property and set that property to null, the ComboBox throws out your binding. No, really. There’s even a Connect bug about it.
For posterity, here is an incredibly simple reproduction scenario. No view models or anything fancy, just one user control:
This code sets up a ComboBox with the appropriate settings, a TextBlock bound to the same property as the ComboBox’s SelectedValue binding, and a button to clear our selection (by setting said property to null). Before we get into code we have to define our “Item” class – when using SelectedValue and SelectedValuePath, we need to be binding to a set of objects:
Very simple, just a class with a Value property. Now for the codebehind of the user control:
This defines the SelectedValue property (and necessary INotifyPropertyChanged implementation), sets the DataContext to itself, and when the button is clicked it sets the SelectedValue property to null. If you’re familiar with Silverlight, nothing here should look out of place.
When the application is run and the ComboBox selection is changed, the TextBlock’s text updates as expected.
When you click Clear selection, both the ComboBox and TextBlock clear:
Finally, making another selection in the ComboBox demonstrates the issue:
What’s going on here? If I put a breakpoint on the SelectedValue property setter…
…execution never stops there! This means my binding, which was working before, is either broken or the ComboBox removed it. Because I’m writing this after the fact, I know that the ComboBox, on a null value in its SelectedValue binding, will clear out the SelectedValue binding. In my application, I like the way the view model is structured and the XAML is laid out and I don’t want to change the way things work, so what do I do? If my binding is being deleted on a null value, can I re-add it? Is that a valid workaround?
Yes, and yes (in my opinion). There are other workarounds such as subclassing ComboBox, but I’m of the opinion that much of the Silverlight and WPF framework code wasn’t written with subclassing in mind and it can be more of a pain to subclass than it is to attach a behavior of some sort to an existing class. In addition to this, I personally find it easier to attach a behavior and if the reason for the behavior is ever fixed, I can simply remove the behavior wherever it’s used. Nice and neat.
So instead of subclassing, I’m going to go with behavior attaching, and this is where the Expression SDK comes in. In a previous post, I mentioned Behaviors, Triggers and Actions and mostly dismissed Behaviors because a behavior is essentially a trigger and an action combined. In this case, it makes no sense to separate our trigger (a null value set on a ComboBox) and our action (fixing the binding on said ComboBox) so it makes sense to keep it all together.
To start, what we need to do is whenever the SelectedValue changes, if it’s non-null, store the current binding. If SelectedValue is ever null, we need to restore the SelectedValue binding onto the ComboBox. To do this, we’ll create a class that inherits from Behavior<T>:
This class has two virtual methods that are important to override: OnAttached and OnDetaching. OnAttached is called when the behavior is loaded and attached to an associated element (ComboBox in my case). On Detaching is called when it is being unloaded from an element (and thus is being detached). In our case, we want to handle the ComboBox.SelectedValueChanged method:
In the event handler, we need to cache the binding when it’s available and restore it when it’s been cleared. To do this, we’ll use the FrameworkElement.GetBindingExpression method to get the binding on the SelectedValue property.
The CacheExistingBinding method stores the binding in a local field, and the SelectionChanged handler restores the cached binding if it’s discovered to be null. With this behavior added to our ComboBox:
The bug no longer affects us and the ComboBox continually updates the binding so the TextBlock displays the active selection.
Converters are a bit of a touchy subject in MVVM. Some would argue that the ViewModel is itself a “converter on steroids” and for the most part I agree, specifically when you are dealing with complex values (“I have an object of type Contract but I want to display a Customer on screen”). My view of MVVM is within view of the dogmatic MVVM, however I also have a strong pragmatic voice in my head telling me not to go overboard on things. So while I do think that a view model should closely resemble the data a view needs, I’m not of the opinion that it must match exactly.
The dogmatic view would mean that if a view needs a Foo formatted in a specific way as a string, then the view model should have a property on it that returns the Foo in that format. For example, if a view needs to display a decimal as a currency, it should have a string property that calls ToString(“C”) on the backing decimal (contrived example, and yes I’m aware of the format string in bindings as of Silverlight 4). I’ve never liked this approach – I would always prefer to have my view model have a decimal property and let the view format the decimal as needed. That’s the point of a view is it not? To format and display the data as needed? Similarly, there are times when I use a single property to power multiple items. For instance, I may have a drop down of choices bound to an enumeration property. At the same time each choice would have its own panel that shows or hides. Some would insist on one property for the drop down and one Visibility property for each of the panels. Personally, I would rather just bind the panels’ visibility directly to the same property as the drop down and use a converter to evaluate it to a Visibility.
For example, instead of this property:
I prefer this property:
To use the second property as the Visibility of a UIElement, I need a converter that is capable of converting a Boolean into a Visibility value. In my opinion, a ViewModel represents the data a view uses and a View should do any transformations necessary to use the data as it sees fit. While building complex Silverlight applications, I often find myself creating properties like the second one above and using them in more than one place on a View. I’m not a fan of inter-element binding when I already have a ViewModel property capable of handling it, so I frequently have situations like below:
The Expression Blend SDK has some interesting controls in it that you can easily miss if you’re not poking around the SDK namespaces. The one I’m going to talk about right now is called LineArrow and is a simplistic way to draw a curved or straight line with optional arrow heads on it. At its simplest, it draws a line from one corner of itself to another corner:
And when executed it looks like this:
To put this to good use, one could arrange a set of visual elements to visualize a process flow perhaps:
And the XAML:
While it may look useful, it may also be a bit of a pain to use in a dynamic view that has to drive the view dynamically. Deciding an ideal bend and the X/Y and Width/Height of the arrow may not be easy on a data driven view, but for a static view this control can certainly be useful.
The Expression Blend SDK has some interesting controls in it that you can easily miss if you’re not poking around the SDK namespaces. The one I’m going to talk about right now is called Callout. The Callout control is a content control that renders itself with an optional arrow anchored at a given point. What makes this control interesting (and fun) is it has an option for a displaying itself light a thought bubble and a word balloon.
The AnchorPoint property dictates where the optional arrow will be anchored on the callout. The CalloutStyle property has 4 options: Cloud, Oval, Rectangle, RoundedRectangle. The first two support arrows and the last two do not. To see this in action:
If I switch CalloutStyle to Cloud and move the anchor point to “0,1” (and move the Callout up a bit with a margin) I end up with this:
And a quick example of Rectangle and RoundedRectangle (which are much more boring without arrows):
When you need a visual element from anywhere other than the main Silverlight namespaces/assemblies, it can be a pain to register namespaces. If I want a control from the Silverlight toolkit System.Windows.Layout.Toolkit assembly:
These are a pain because either you wait for Intellisense to pop up once the cursor is inside the quotation marks (I’ve noticed some don’t even realize Intellisense works here as it can sometimes take so long to open) or you memorize the format. You can also use Resharper, but that defeats the purpose of what I’m about to discuss.
Once I have registered my namespace and namespace prefix, I can use the prefix to specify things in the associated assembly/namespace:
What if I wanted to register the System.Windows.Controls.Data.Toolkit assembly as well? Here comes another namespace!
And so on, compounded with my own user controls, converters, etc, until I end up with tens of namespaces on all of my XAML files. Luckily Microsoft did think of this and provide us with a simple shortcut. To see it in action, start declaring a namespace but let Intellisense open:
What you see here are a number of XML namespaces defined that contain multiple .NET namespace and assembly combinations. With this one namespace declaration:
…I have access to everything in the Silverlight Toolkit. If you are using any of the Expression Blend SDK, there are some namespaces you can register for them as well:
These can be incredibly useful when dealing with Microsoft’s various extension libraries, but what about my libraries? I tend to write a lot of reusable converters, user controls, view models, etc. To enable this with my own code, I simply need to use the XmlnsDefinitionAttribute.
When I do this, I now have access to all my registered namespaces via the “http://foo.bar” XML namespace.
As I build up a library of shared code, I can easily reference my shared code in XAML via these defined XML namespaces and save myself the hassle of having to manually register individual assemblies and namespaces.
One type of Trigger available in the Expression SDK is the DataTrigger. This a trigger that uses a Binding to determine when to execute its actions. If you are using MVVM (or any other pattern that relies heavily on view models or presentation models), this class is a perfect way to interact with the UI without needing to write any custom code in the model or codebehind.
For the purpose of this post, I’m going to be creating a simple header/button control that is powered by a view model and alters the user interface of the control based on data changes.
The view model representing the 3 header controls:
Nothing special here, it’s a simple class that notifies on property changed and provides an image, text and an enabled Boolean property. The concept here is the application will have one or more headers that can be enabled or disabled and are intended to give the user visual feedback when the change happens.
Next we need to create a UserControl to provide a visual representation for our header:
As it stands like this, the images and text appear but when the application disables a header, the control doesn’t know. One solution to this would be to find a way to bind the IsEnabled property to one or more visual properties inside this control and create one or more converters to convert from true/false to the appropriate values. For instance, suppose we had a converter that converted from Boolean to Colors. We could change the color of the TextBlock easily:
While this is easy to do (and I’ve done it numerous times), if there are multiple visual properties you have to deal with you’ll need to create more bindings and more converters. It’s not the best solution if you need to change a lot of properties. So what can we do better? A storyboard with a DataTrigger:
The DataTrigger uses a Binding to the IsEnabled property and when it’s a specific value (false or true), we use a ControlStoryboardAction (also from the Expression SDK) to begin a storyboard to perform our desired animations. When our header is disabled, we’ll change the image to black & white, change the text color to light gray and shrink the text. Here are the storyboards to do this:
In DisableStoryboard we use the ColorToneEffect bitmap effect to convert the image to black and white (this effect is also provided by the Expression SDK). After that we use a standard ColorAnimation and DoubleAnimation to perform the rest of the animations (text color and font size).
With these added, clicking the toggle buttons disables our headers and performs the desired animations:
For reference here is my MainPage.xaml:
And the codebehind for it:
And the full header control:
Prior to the Expression SDK, you had two main choices to create reusable behaviors that could be applied to UI elements. First and most obvious is to subclass a control type and add whatever functionality you wanted. For instance, if you wanted a TextBox to raise an event (or execute an ICommand) whenever the Enter key was pressed, you could create a subclassed TextBox and add that.
The second way was to create manual “attached behaviors” via a trick commonly used in WPF with attached properties. In short, you create an attached property and use the property change notification to attach to events. Using the earlier example, here is a working attached behavior that exeuctes an ICommand on enter key press in a TextBox:
The meat of the code comes from lines 36-60. On 40-45, we attach or detach an event handler to the KeyDown event depending on whether the supplied ICommand is null. Then on lines 49-60 we handle the KeyDown event and execute the command. To use this behavior, just reference it inside a TextBox:
All that is needed is the ViewModel/DataContext expose an ICommand property called ExecuteSearch and now we’ve got a way to repeatedly apply a common behavior to any TextBox in our application without much effort.
One thing you may notice here, however, is our behavior describes not only the action to be taken, but also the condition in which it happens. This is limiting and can end up causing duplicated code as we create variants of our shared behaviors. Enter the Expression SDK.
The Expression SDK (in particular, two assemblies: System.Windows.Interactivity and Microsoft.Expression.Interactions) breaks this up into separate concerns. With it you can create the “when” (a trigger for instance) and the “what” (an action for instance) separately to more easily mix and match. In the Expression SDK there are behaviors, triggers and actions. Behaviors are all-in-one sets of reusable functionality like we did above, but from here on I’ll only be discussing triggers and actions, which enable us to separate the when and the what.
The trigger for the enter key pressed behavior is the enter key being pressed inside a TextBox. To represent this, we create a class that inherits from TriggerBase:
We override OnAttached and subscribe to the TextBox’s KeyDown event and when the Enter key was pressed we call the InvokeActions method. Very svelte and to the point. What about the action though? Luckily, the Expression SDK has support for invoking a command built in via the InvokeCommandAction, so we’re done except for our XAML:
What if we wanted to do something other than invoke a command? With the full DIY attached property behavior, we’d have to create a new class that contained the new behavior. By factoring our trigger out into a class, we can use any of the built-in actions. What if we wanted to set the user control’s background to green?
If you have an action that’s not natively supported by the Expression SDK, you can create a class that inherits from TriggerAction.
For more info, see this Expression blog post on Behaviors, Triggers and Actions.
At some point, every .Net developer comes across WebRequest.Create. It’s a simple way to create any type of request to a web resource, frequently an HTTP resource. In Silverlight there is an alternate method you can use as well: WebRequest.CreateHttp. I swore until a couple minutes ago that method has existed in the full .Net framework for ages, but MSDN and Visual Studio are telling me otherwise.
Regardless, looking at the documentation for CreateHttp it appears to only support “http” or “https” requests, and returns an HttpWebRequest instead of a plain old WebRequest. To me, this seems like a convenience method: Microsoft’s developers realized the majority of the use of this class is for HTTP web requests, so why not eliminate some casting?
Unfortunately that’s not the case. Here is why it’s not the case. Given this code, should the output be the same?
Ah, if only:
Turns out, when you use CreateHttp, it is created with the ClientHttp browser stack. For more information on the different network stacks, see here.
Why does this matter? Well, if you are using the default behavior of Silverlight (browser stack), rely on cookies of any sort (session, authentication, etc) and create a web request to your server manually that needs those cookies (again, for authentication, session, etc), any web requests created via CreateHttp will not pass your cookies to the server. Authentication won’t work, you won’t have the same session you do if you use RIA, WCF or WebRequest.Create.
This recently came up at one of my clients. The Silverlight application uses both Windows authentication and Forms authentication to log in (both handled from within the application itself with a backing website and Membership provider). The first step is to try to auto-login the user with a WebRequest.Create to the page that forces Windows authentication (the whole site can’t require Windows auth as we have to support external users as well). If that succeeds a FormsAuthentication ticket is passed back to the client in the form of a cookie. The problem here is, we’re using the browser HTTP stack (on purpose) but I was using CreateHttp to create the WebRequest (because it felt like a convenience method). By using CreateHttp, none of my cookies created inside the Windows authentication page were being used by my WCF or RIA service calls (that were using the BrowserHttp stack). Simply switching to the Create method shared all my cookies across WCF, RIA and WebRequests.