Random thoughts for this week

View uptown from 86th floor of Empire State BuildingI may have found a viable option for printing panoramic photos that links in nicely with my SmugMug account.



Geekbrief_tv The internet TV options in Windows Media Center works much better in the States that it ever did for me back in Oz. I quite like geekbrief as just one of the many tech gadget shows.


HDR-CX550VDCR-PC100EI finally got around to replacing my trusty video camera – a Sony DCR-PC100E purchased back in 1999. It was one of the early Mini DV cameras, packed full of manual options in what was then an incredibly compact body. In fact the camera I’m replacing it with (HDR-CX550V) is about the same weight and size and has pretty much the same feature set (viewfinder, manual focus, night shot). Of course everything is now HD and records to memory rather than tape which makes all the difference. I guess the main sign of progress though is that the new camera cost me 1/4 of what I paid for the old one.

Having now had the chance to see an play with one first hand, I’m more convinced than ever that the iPad is an awkward form factor that just doesn’t compete well with the existing alternatives. I almost laughed out loud when I saw a guy trying to play a game on one in a busy subway. Kudos to him for being such a die-hard fan!

Rob Relyea sparked an interesting discussions on Sliverlight vs WPF which was fairly relevant to some talks we’ve been having at work recently. I was so impressed by the first commenter’s response – Mike Strobel – that I subscribed to his blog where he also had a very interesting take on the Windows Phone 7 UI. I have to admit I share many of Mike’s misgivings about the new UI.

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()
this.viewModel = new ViewModel();
this.DataContext = viewModel;
this.timer = new DispatcherTimer(
new TimeSpan(0, 0, 1),
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"
Title="MainWindow" Height="350" Width="525">
<StackPanel Width="150">
Text="{Binding Value,StringFormat=0.00,UpdateSourceTrigger=PropertyChanged}"/>

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"
Title="MainWindow" Height="350" Width="525">
<StackPanel Width="150">
Text="{Binding ModifiedValue,StringFormat=0.00,
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
return this.modifiedValue;
if (this.modifiedValue != value)
this.modifiedValue = value;
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 =
typeof(TextBoxExtensions), new FrameworkPropertyMetadata(
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.

Text="{Binding Value,StringFormat=0.00,
local:TextBoxExtensions.NonIntrusiveText="{Binding Value,StringFormat=0.00,