Category Archives: Lab49

Silverlight Firestarter 2010

Silverlight Firestarter 2010 Banner

Spawned from a communication at the recent PDC that was then somehow twisted and blown well out of proportion by the blogosphere, Microsoft recently held a Silverlight Firestarter event on campus in Redmond (and streamed live). The “main event” was the keynote which was primarily dedicated to talking about the future of Silverlight, and specifically show casing Silverlight 5.

What was announced

The current feature set of Silverlight 5 is impressive – see Scott Gu’s blog post for a comprehensive overview, the official futures page, or better yet go watch the keynote here.

Here’s what I’m looking forward to the most:

  • Implicit DataTemplates. How do Silverlight developers survive without this!?
  • AncestorType support for RelativeSource binding.
  • Data binding debugging. This looks awesome and could be a real time saver. Simply place a breakpoint on the binding declared in the XAML. When the debugger stops it gives you full access to the Target and binding results or error. This surely has to make it into WPF in an upcoming Visual Studio service pack, or at the very least vNext.
  • For shear, jaw dropping visual effect the 3D medical modelling and globe demos were spectacular. Though it was a very quick portion of the demo the 3D globe – with separate land and cloud layers looked great. I hope this is the future for Bing maps now that they’ve scrapped the 3D plug-in version.
  • BI with Project Crescent. So this offering was shown at the recent PASS 2010 Summit and its seriously cool.

Timing

The problem of course is that the release date for Silverlight 5 isn’t until late 2011 – effectively a year away. Its understandable that Microsoft hadn’t originally planned on showing off Silverlight 5 until they were closer to the release – probably at the time the first beta (scheduled for Spring 2011). It seems they felt that their hand was forced by the recent “Silverlight is dead” debacle. What I saw demoed was certainly impressive but it really makes me crave those features now – and makes Silverlight 4 seem more incomplete as a result. It isn’t helped that Silverlight for Windows Phone is currently not even at Silverlight 4 level. So for now I get to develop on Silverlight 3.5 and 4.0 whilst eagerly awaiting the promise that is Silverlight 5.

Of course any serious development I do is in WPF – ‘cause lets face it – browser dependent apps are just toys right?

Intro Sessions for Silverlight

The rest of the Firestarter event was devoted to standard presentation sessions. It started with a Silverlight Binding 101 session given by Jesse Liberty. This should have been dull, but Jesse was very entertaining. If you’re very new to the Silverlight scene I strongly recommend his session as an introduction. John Papa also did a very good introduction to MVVM session.

Each session gradually increased in terms of depth of coverage. The last session by Jamie Rodriguez was a fast and furious dive into potential performance issues when developing for Windows Phone 7. It covered many pragmatic tips and tricks on monitoring and resolving these issues. Despite having seen much of this content previously presented by Jamie on Channel 9 I still found it to be a great session.

The Venue

Microsoft Campus SignThis was my first trip to Seattle and unfortunately I was on a very tight schedule. I arrived very early Thursday morning and left the same night (with 6 hours of flight time either side). I caught the local bus from my hotel in Bellevue to the campus and the area looked very suburban, yet very beautiful too (certainly compared to the concrete jungle that is Manhattan). I also had a detour through downtown Seattle on the way back to the airport in a taxi I was sharing. I was impressed with the city, though I’m told the real test as to whether you could live in Seattle is being able to live through your first winter there.

The event was held in Building 33 at the Conference Center. The room used to host the keynote and the developer sessions was a lecture theatre layout. This was awesome ‘cause it meant everyone could have their laptops set up the entire day, plugged in to power, recharging phones etc. I think about one third of the attendees at the keynote were Microsoft employees from teams other than the Silverlight team.

Is Silverlight Resuscitated?

So will this Firestarter event satisfy the seemingly fickle Silverlight development community? Will they be prepared to wait more that 12 months between versions (shock, gasp)! I heard someone in the audience complain that there wasn’t enough Windows Phone content – which was kind of amusing. Too much focus on Windows Phone would have probably been exactly the wrong message to send to the community.

So where does this leave WPF? No mention in the PDC keynote, no separate Firestarter event – is WPF dead!? Bring on WPF Firestarter 2011 Smile with tongue out

Preventing a bound TextBox from resetting the caret position

Someone posed a question on our internal mailing list today at work that reminded me of a problem I’d tackled previously whilst working as a developer of fortune.

Here’s the challenge. A TextBox is bound to a data value that is being constantly updated. In my scenario the TextBox was bound to a data feed coming from a serial port connected weigh bridge. Even though the value is being automatically updated the operator has the ability to override the value with their own – at which point it would normally cease being updated by the data service.

Sounds fairly straight-forward. The main problem is that every time the TextBox value is updated via data-binding the selection text and position of the caret is reset. This is particularly annoying if the operator positions the caret about to make their change and a fraction of a second before they press a key the caret moves to the left edge.

I can’t remember exactly how we solved this problem in my earlier engagement (Raaj if you’re listening you could jog my memory) but here was my quick re-attempt.

First I’ll set the scene with a mock environment.

public partial class MainWindow : Window
{
private ViewModel viewModel;
private DispatcherTimer timer;
public MainWindow()
{
InitializeComponent();
this.viewModel = new ViewModel();
this.DataContext = viewModel;
this.timer = new DispatcherTimer(
new TimeSpan(0, 0, 1),
DispatcherPriority.Background,
UpdateValue,
this.Dispatcher); } private void UpdateValue(object sender, EventArgs e) { this.viewModel.Value += 0.01; } }

This sets up a simple form whose DataContext refers to a ViewModel with a Value property. The Value property is updated every second by a thread safe timer.

<Window x:Class="TextBoxOverlay.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Width="150">
<TextBox
Text="{Binding Value,StringFormat=0.00,UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</Window>

The XAML simple binds a TextBox to the Value property. Running this sample and the problem can be immediately realised. Attempting to edit the value in the TextBox using the keyboard is extremely frustrating. The caret won’t go where you want it to.

So – the next step is to create a TextBlock that overlays the TextBox and instead bind this to the Value property. We set the IsHitTestVisible property on this TextBlock to False so that the user can still interact with the TextBox underneath. Then – and this is where things get a little sneaky – we make the TextBox’s text transparent. This allows us the strange freedom to interact with the TextBox’s content by selecting it and moving the caret – and because we can see the same text in the overlaid TextBlock things appear as normal.

<Window x:Class="TextBoxOverlay.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Width="150">
<Grid>
<TextBox
Text="{Binding ModifiedValue,StringFormat=0.00,
UpdateSourceTrigger=PropertyChanged}"
PreviewTextInput="TextBoxPreviewTextInput" Foreground="Transparent"/> <TextBlock IsHitTestVisible="False" Margin="5,0" Text="{Binding Value,StringFormat=0.00}"/> </Grid> </StackPanel> </Grid> </Window>

You can see from the XAML that the TextBox is bound to a new field on our ViewModel called ModifiedValue. We also hook up to the PreviewTextInput event. We could have used an attached behaviour here rather than resorting to code-behind – but I wanted to keep things simple. So the code behind on the form has:

        private void TextBoxPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var textBox = sender as TextBox;
var selectionStart = textBox.SelectionStart;
var selectionLength = textBox.SelectionLength;
var caretIndex = textBox.CaretIndex;
this.viewModel.ModifiedValue = this.viewModel.Value;
textBox.CaretIndex = caretIndex; 
textBox.SelectionStart = selectionStart; textBox.SelectionLength = selectionLength; }

Here we save and restore the TextBox’s SelectionStart, SelectionLength and CaretIndex whilst updating the ModifiedValue that is about to be changed to equal the Value that the user can actually see (remember the ModifiedValue is transparent).

The very last trick is within the ModifiedValue’s setter where we update the Value property. This ensures that whatever changes the operator makes to the TextBox are visible in the overlaid TextBlock. Of course the whole point of doing all of this is that the caret position and selection remains completely unchanged whilst the value appears to update.

        public double? ModifiedValue
{
get
{
return this.modifiedValue;
}
set
{
if (this.modifiedValue != value)
{
this.modifiedValue = value;
NotifyPropertyChanged("ModifiedValue");
if (this.ModifiedValue.HasValue)
Value = ModifiedValue.Value;
}
}
}

Source code here.

So aside from the tacky code-behind to keep the code here to a minimum, I’m wondering if there isn’t a neater solution?

UPDATE: Using an attached behaviour

It was pointed out to me by a colleague that there is a simpler, more versatile solution. Simple encapsulate the text change with selection restore within an attached property. Then we can use multiple bindings to achieve the effect.

        public static string GetNonIntrusiveText(DependencyObject obj)
{
return (string)obj.GetValue(NonIntrusiveTextProperty);
}
public static void SetNonIntrusiveText(DependencyObject obj, string value)
{
obj.SetValue(NonIntrusiveTextProperty, value);
}
public static readonly DependencyProperty NonIntrusiveTextProperty =
DependencyProperty.RegisterAttached(
"NonIntrusiveText",
typeof(string),
typeof(TextBoxExtensions), new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
NonIntrusiveTextChanged)); public static void NonIntrusiveTextChanged(
object sender,
DependencyPropertyChangedEventArgs e) { var textBox = sender as TextBox; if (textBox == null) return; var caretIndex = textBox.CaretIndex; var selectionStart = textBox.SelectionStart; var selectionLength = textBox.SelectionLength; textBox.Text = (string) e.NewValue; textBox.CaretIndex = caretIndex; textBox.SelectionStart = selectionStart; textBox.SelectionLength = selectionLength; }

Now the XAML no longer requires the tricky TextBlock overlay, we simple have a TextBox with two bindings.

<TextBox
Text="{Binding Value,StringFormat=0.00,
UpdateSourceTrigger=PropertyChanged,
Mode=OneWayToSource}"
local:TextBoxExtensions.NonIntrusiveText="{Binding Value,StringFormat=0.00,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"
/>