Impossible love

Dedicated to the endless frustrations of trying to make these damn machines do what we want them to do...

Dedicated to the endless frustrations of trying to make these damn machines do what we want them to do...

Daniel Stolt's Blog

Let him who is without sin DirectCast the first Object.

How Microsoft Leaves Windows Mobile Developers to Rot in Hell

Categories: English | Programming | Rants | Windows   Tags: | | |

I do a lot of work for a company that builds line-of-business applications based on Windows Mobile and .NET Compact Framework. Our apps are typically run on business-oriented Windows Mobile devices, most often ruggedized hardware built by manufacturers such as Intermec or Symbol. For a long time we’ve been wondering what’s going on with Windows Mobile development with respect to Visual Studio 2010 and future versions. There are significant limitations in the current development stack in terms of user experience, and for a long time we’ve had an almost desperate need to know the roadmap of these things.

Therefore, I’m currently at MIX in Las Vegas to get as much information as possible on what’s really going on with the developer story around Windows Mobile (no, not Windows Phone development – that stuff is pretty obvious – what we need to find out is what’s going on with Windows Mobile development). And what I’ve found out so far is not uplifting. Frankly, I’m pissed off to the point where I need to write about it, so here’s the story. It’s a complicated situation, so bare with me.

The Past

When Visual Studio 2010 Beta 1 came out, all mobile development features (Smart Device projects, .NET Compact Framework, Mobile WinForms designer, Device Emulator etc.) were mysteriously missing. People started asking questions, but Microsoft was almost completely silent. A few vague mentions here and there stated that “Microsoft was committed to providing mobile development support for Visual Studio 2010, but could not share more information at this time”.

When Visual Studio 2010 Beta 2 came out, mobile development support was still MIA. People such as me, and dev shops such as the one I work for, started worrying. Microsoft remained largely silent, but started saying “we’ll have more to say at MIX”.

When Visual Studio 2010 RC saw the light of day, mobile development support was still nowhere to be seen. Hopes started fading that the mobile development features would be reintroduced into the product, because by now it was surely too late. Let’s face it: if a major block of functionality is not in the RC, it’s not going to be in the RTM build either.

All through this time, details started to emerge about Windows Phone 7, and it was obvious that it was a very different beast. It gradually became obvious that the developer story around Windows Phone 7 would be totally awesome, that it would revolve around Visual Studio 2010 and Expression Blend 4, and that it would involve Silverlight and XNA. But confusion remained around how this related to Windows Mobile 6.5 and below. Would existing Compact Framework application carry forward to Windows Phone 7? Would the new development stack also run on Windows Mobile 6.5 and below? What the hell were we supposed to do with all existing Windows Mobile applications if Visual Studio 2010 could not be used to work on them? Would we be stuck with Visual Studio 2008? You get the idea.

I was at PDC09 in Los Angeles in November last year and tried to get some of these questions answered. Well, that didn’t happen. Not only was the whole event very low on Microsoft representation (probably because the economy went down the drain that year), but the people who were actually there closed like clams as soon as anyone mentioned the word “mobile”. Apparently, because anything related to Windows Phone 7 was under such heavy secrecy, things such as Windows Mobile development support in Visual Studio 2010 became subject to the some secrecy sort of by association, even though they really had nothing to do with any of the stuff that was so sensitive. A Microsoft employee listened politely to my questions during Ask the Experts, asked me to send them in email to him, and promised to get back to me with answers. That never happened, despite sending friendly reminder emails twice.

Then a few weeks ago Windows Phone 7 was officially unveiled, and any development-related questions were answered with the standard “ask us again at MIX”.

The Present

After speaking to some Microsoft people here at MIX this morning, I can now confirm the following.

  1. Applications written for .NET Compact Framework 3.5 on Windows Mobile 6.5 and earlier will not run unmodified on Windows Phone 7. Parts of the code will carry forward, because things are still .NET. Basically, anything that does not deal with UI and does not do COM or Win32 interop should carry forward with relative ease.
  2. The development stack for Windows Phone 7 is brand new (based on Silverlight and XNA) and will not support Windows Mobile 6.5 and earlier. It is not an evolution of the mobile development features in Visual Studio 2008, but rather it was built from scratch using newer technologies and targeting only Visual Studio 2010.
  3. The mobile development tools for .NET Compact Framework 3.5 and Windows Mobile 6.5 and earlier will not be re-added to Visual Studio 2010. Developers writing apps that need to run on Windows Mobile 6.5 and earlier will have to keep using Visual Studio 2008.
  4. Microsoft will not continue to innovate on Windows Mobile 6.5 and earlier, nor on the development tools targeting that platform.
  5. If you’re writing business-oriented apps for business-oriented devices (e.g. the kinds of devices that Intermec and Symbol et. al. are making, typically ruggedized and equipped with barcode readers etc.) you are not likely to be coding for Windows Phone 7 anytime soon, because Windows Phone 7 currently is almost exclusively consumer-oriented and the chances of these device makers making devices based on Windows Phone 7 are very slim, for a number of reasons.
  6. Applications on Windows Phone 7 will run in a tightly controlled managed sandbox, and interop with device hardware is limited to the kinds of interactions that Microsoft decides to surface first-class in the managed APIs (typically cameras, sensors, etc.) That means no such stuff as barcode readers. However, there is an interesting possibility for device makers to expose additional custom hardware as local IP endpoints so that applications could potentially communicate with them using the network stack.
  7. SQL Server Compact will not be available on Windows Phone 7.

The combination of these facts leaves shops like us in a veritable twilight zone. We would like nothing more that to rewrite our apps using the new platform and developer stack. Unfortunately, that’s not our call to make. There is a solid barrier between the Windows Mobile 6.5 world on one side, and the Windows Phone 7 world on the other. Neither the development platforms nor the apps written for them can cross this barrier. Hence, the devices we target need to move to the new platform first, which is unlikely to happen. So we are forced to stay on the old developer platform, which means not only continuing to struggle to create anything beyond the most primitive of user experiences, but also doing so in an old and outdated IDE!

Now, I’m usually a very vocal advocate of making clean breaks with the past in order to create something better for the future, so when Microsoft finally does exactly that, shouldn’t I be happy? Well, if you think about it, that’s not at all what they are doing here. Rather, they are leaving something existing behind in favor of something brand new that serves a completely different purpose. Windows Phone 7 does not replace Windows Mobile 6.5, because the former is completely consumer-oriented whereas the latter is primarily enterprise-oriented. The new development platform as shown off today here at MIX is simply outstanding, breathtaking, amazing – it’s everything we want mobile development to be! There’s just one problem: it targets a completely different set of devices and customers, and therefore we don’t get to code for it.

In other words, we now actually have two completely separate mobile development platforms, with completely different target devices and customers. The “older” platform will still be around for quite a while, because there’s nothing yet to replace it - I’m fine with that! There is no compatibility or interop between these two platforms – I’m fine with that too! What I’m not fine with is the fact that the older platform is not carried forward as-is to run within Visual Studio 2010! The fact that the newer platform also has the word “mobile” in its description is not a valid reason, because they really have nothing to do with one another. The fact that they both deal with mobile development is almost coincidental.

I’m not asking for a new and greatly improved version of the Windows Mobile 6.5 developer stack (although that would have been nice) – I understand that Microsoft chose to focus on the consumer story now. I’m only asking that they allow us to keep using the same developer stack with the new IDE, so we can at least take advantage of the IDE and language improvements. Including the existing mobile developer toolset in Visual Studio 2010 in addition to the new stuff would have been the right thing to do, and I can’t imagine that it would have been particularly hard. Instead, they just chose to drop it from the product, leaving Windows Mobile 6.5 developers to rot in hell with Visual Studio 2008. That’s what pisses me off.

The other thing that pisses me off is that Microsoft has been so nonchalant about informing software vendors of their plans. A lot of shops (including ours) could have really used this information a year ago when the decisions were made (and believe me, we have really been trying hard to get these answers). It would have helped a tremendous deal in our strategic planning to know that the platform on which we have bet our business would be dropped from Visual Studio in the 2010 timeframe. This information could have been shared publicly without disclosing anything about Windows Phone 7, and that would have been the right thing to do.

The Future

Looking forward, I have heard some hints today that the enterprise side of things is being discussed and thought about for the future. Microsoft focused on the consumer story for this release to fend off the competition in that space, but a more business-oriented version of Windows Phone 7 and the accompanying developer stack might very well be coming in the future. Essentially built on the same stack of technologies, but with a less constrained runtime execution environment and a different deployment story.

If and when that happens, devices makers such as Intermec and Symbol would be more likely to get on the new platform, and then shops like ours could move away from the old platform for good. For now, however, we are left to rot in hell.

Translating Numeric Values Between Different Scales in WPF Data Binding

Categories: Programming | English   Tags: | |

A while back I wrote a WPF application in which I wanted to bind several things to the value of a Slider control. In this case, I wanted the Slider to control both the size and the opacity of an Image, so that when the user moved the slider from right to left, the Image would become smaller and fade out of view. The problem was of course that the value of the Slider could not be made to directly correspond to the to the value of both the size and the opacity of the Image, because those values were on a different scale.

To put this into more concrete terms, the opacity of the Image must be specified as a value between zero and one, while I wanted the size of the Image to vary between 100 and 500 pixels (both width and height). So, no matter what I use as the Minimum and Maximum values of the Slider, there is no way I can directly bind both the opacity and the size of the Image to the value of the Slider. I needed some way to translate the value of the Slider onto a different scale for each of the bindings.

I quickly realized this was a general problem, looked through the WPF documentation and did some googling on the subject, came up empty and therefore, as we programmers like to do, set out to build a generic solution. Now, I don’t consider myself a WPF expert, and I suspect there might be a simpler way to do this. If there is, I’d love to hear about it. Nonetheless, here is a brief run-down of what I did in case it might help somebody facing the same problem.

IValueConverter to The Rescue

In WPF data binding, there is the concept of a value converter, which is a mechanism by which we can write custom code to convert values between the source and target end of a binding. This mechanism is implemented by means of the IValueConverter interface and the ValueConversionAttribute.

Here’s a few words form the documentation:

If you want to associate a value converter with a binding, create a class that implements the IValueConverter interface and then implement the Convert and ConvertBack methods. Converters can change data from one type to another, translate data based on cultural information, or modify other aspects of the presentation.

There are a few built-in converter classes in WPF which implement the IValueConverter interface:

  • AlternationConverter
  • BooleanToVisibilityConverter
  • ZoomPercentageConverter
  • JournalEntryListConverter

None of them are applicable to our scenario. Clearly, we need another type of converter that will allow us to do arbitrary translation of values fron one scale onto another, and that will allow us to specify the source and destination scales on a per-binding basis.

A Reusable Translator Class

So, let’s create a class that implements IValueConverter and that maps the source value of the binding on one scale to the destination value of the binding on another scale. Let’s call the class Translator for simplicity. To begin with, here’s code for Translator in its entirety:

   1: Imports System.Globalization
   2: Imports System.Windows.Data
   3:  
   4:  
   5: <ValueConversion(GetType(Double), GetType(Double))> _
   6: Public Class Translator
   7:     Implements IValueConverter
   8:  
   9:  
  10:     Sub New()
  11:         m_SrcMin = 0
  12:         m_SrcMax = 1
  13:         m_DstMin = 0
  14:         m_DstMax = 1
  15:     End Sub
  16:  
  17:  
  18:     Sub New(ByVal srcMin As Double, ByVal srcMax As Double, _
  19:             ByVal dstMin As Double, ByVal dstMax As Double)
  20:         m_SrcMin = srcMin
  21:         m_SrcMax = srcMax
  22:         m_DstMin = dstMin
  23:         m_DstMax = dstMax
  24:     End Sub
  25:  
  26:  
  27:     Private m_SrcMin As Double
  28:     Private m_SrcMax As Double
  29:     Private m_DstMin As Double
  30:     Private m_DstMax As Double
  31:  
  32:  
  33:     Public Property SrcMin() As Double
  34:         Get
  35:             Return m_SrcMin
  36:         End Get
  37:         Set(ByVal value As Double)
  38:             m_SrcMin = value
  39:         End Set
  40:     End Property
  41:  
  42:  
  43:     Public Property SrcMax() As Double
  44:         Get
  45:             Return m_SrcMax
  46:         End Get
  47:         Set(ByVal value As Double)
  48:             m_SrcMax = value
  49:         End Set
  50:     End Property
  51:  
  52:  
  53:     Public Property DstMin() As Double
  54:         Get
  55:             Return m_DstMin
  56:         End Get
  57:         Set(ByVal value As Double)
  58:             m_DstMin = value
  59:         End Set
  60:     End Property
  61:  
  62:  
  63:     Public Property DstMax() As Double
  64:         Get
  65:             Return m_DstMax
  66:         End Get
  67:         Set(ByVal value As Double)
  68:             m_DstMax = value
  69:         End Set
  70:     End Property
  71:  
  72:  
  73:     Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, _
  74:                             ByVal parameter As Object, ByVal culture As CultureInfo) _
  75:                             As Object Implements IValueConverter.Convert
  76:         Dim src As Double = CDbl(value)
  77:         Dim dst As Double
  78:         If src < m_SrcMin Then
  79:             dst = m_DstMin
  80:         ElseIf src > m_SrcMax Then
  81:             dst = m_DstMax
  82:         Else
  83:             dst = (src - m_SrcMin) / (m_SrcMax - m_SrcMin) * (m_DstMax - m_DstMin) + m_DstMin
  84:         End If
  85:         Return dst
  86:     End Function
  87:  
  88:  
  89:     Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, _
  90:                                 ByVal parameter As Object, ByVal culture As CultureInfo) _
  91:                                 As Object Implements IValueConverter.ConvertBack
  92:         Dim dst As Double = CDbl(value)
  93:         Dim src As Double
  94:         If dst < m_DstMin Then
  95:             src = m_SrcMin
  96:         ElseIf dst > m_DstMax Then
  97:             src = m_SrcMax
  98:         Else
  99:             src = (dst - m_DstMin) / (m_DstMax - m_DstMin) * (m_SrcMax - m_SrcMin) + m_SrcMin
 100:         End If
 101:         Return src
 102:     End Function
 103:  
 104:  
 105: End Class

Now let’s walk though this code from the top.

First of all, Translator needs to be decorated with the ValueConversionAttribute to let WPF and designer tools such as Expression Blend know what specific types this converter converts between. Ideally, Translator would be a generic class where the type of the value could be specified as a type parameter, but there are a number of reasons why this is difficult to achieve in this case:

  1. Instantiating a generic type from XAML markup is not possible, at least to my knowledge.
  2. The type parameter would need to be specified in the ValueConversionAttribute above our class but .NET does not allow for such a construct.
  3. There is no mechanism by which we can limit the type parameter to numeric types on which the arithmetics in our code can be performed.

So, we are limited to using System.Double as the type on which Translator can operate. This is fine, because most numeric properties in WPF that we might need to translate in this manner are indeed exposed as System.Double.

Second, we need some properties and constructors. The source and destination scales can be specified using their respective min and max values, so besides implementing the methods of IValueConverter, our class needs 4 properties. The default constructor initializes those with reasonable (but mostly useless) default values. We also provide a constructor where these values can be specified. This is convenient when you want to instantiate Translator from code instead of markup.

Third, we need to implement the Convert and ConvertBack methods of IValueConverter to perform the actual translation. One thing to note here is that this code also truncates the source and destination values to be within the minimum and maximum values specified for their respective scales. This is something you might want to do differently in your own implementation, opting instead to allow linear projection of the values outside the specified minimum and maximum.

Using Translator from XAML

Allright, now that we have our Translator, let’s put it to some use in XAML. First of all we need to declare an XML namespace that maps to whatever CLR namespace in which Translator happens to reside. In my case it lives in the namespace Perceptible.Utils.Wpf, so I add the following namespace declaration to my Window:

   1: <Window
   2:     ...
   3:     xmlns:utils="clr-namespace:Perceptible.Utils.Wpf">

Next we need to create a couple of instances of Translator to do the translation for us. Remember, in my case I want to bind the size and opacity of an Image to the value of a Slider, so I need two Translator instances each with different destination scales. The easiest way to create those is to add them to the resource collection of the Window:

   1: <Window.Resources>
   2:     <utils:Translator x:Key="OpacityTranslator" SrcMin="0" SrcMax="1" DstMin="0" DstMax="1"/>
   3:     <utils:Translator x:Key="SizeTranslator" SrcMin="0" SrcMax="1" DstMin="100" DstMax="500"/>
   4: </Window.Resources>

Finally, to tie it all together, we just need to specify that these Translator instances be used as value converters in our bindings. We want to bind the Opacity, Width and Height properties of the Image element to the Value property of the Slider, but using different value translation. If you’re using Expression Blend there’s nice GUI support to do this, but in case you’re not here’s the appropriate markup to do the binding (all the other attributes of the Image element are omitted for clarity):

   1: <Slider x:Name="FadeSlider" Minimum="0" Maximum="1" Value="1" />
   2: <Image Opacity="{Binding Path=Value, Converter={StaticResource OpacityTranslator}, ElementName=FadeSlider, Mode=Default}"
   3:        Width="{Binding Path=Value, Converter={StaticResource SizeTranslator}, ElementName=FadeSlider, Mode=Default}"
   4:        Height="{Binding Path=Value, Converter={StaticResource SizeTranslator}, ElementName=FadeSlider, Mode=Default}" />

That should be it. Hope someone out there finds this useful! And like I said, if you know of another way to accomplish this, I would love to hear about it, so leave a comment or drop me a message.

Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Recent comments

Comment RSS