A hidden bug in Windows Store’s ComboBox

Since some time ago I’ve been using Immutable Collections as much as I could due to their immutability contract – nothing ever changes. So far so good, but today I’ve stumbled upon an odd and occasional (at least at beginning) bug with Windows Store/8.1 ComboBox bound to an ImmutableList<T> through ItemsSource property.

I was sporadically seeing crashes in application mostly when ComboBox was somehow in between changes on the page. The random crashes is really the worst type of problem one can imagine. The Exception wasn’t saying much but it put me on the right track. It said that it couldn’t cast ComboBoxItem to T (of which ImmutableList I was using) in ImmutableList<T>.IList.IndexOf(object item) method.

Luckily I’ve found a way to crash it easily – just fill more than 10 items as ItemSource, focus ComboBox and press up or down. It would crash after 5 or so changes each time. Being able to repro the problems asap and 100% reliable is a big benefit. Huge actually.

Then I’ve exprerimented with a normal List<T> instead of an immutable one and it worked without any problem. Odd, I thought.

Now, luckily Immutable Collections are open source on github as a part of corefx. I was being ready for a pull request if I could fix the bug. I was cloning the repository in no time and then tried to reference sources instead of NuGet package. There were two obstacle on my way:

  1. The version of Immutable Collections in corefx is using .net 4.5 which is not a good framework for a Windows Store app. Hence I created a blank Windows Store library and copied all sources there. That worked almost perfectly.
  2. Exceptions were using localized strings from a static class SR which I really didn’t have time to figure out where it comes from. I merely commented out these exceptions and replaced them with new Exception();

At this point the project compiled and I was ready to debug with sources. And soon it stopped in the offending method: ImmutableList<T>.IList.IndexOf(object item). The thing is that ComboBox was passing an ComboBoxItem (even though I was using items of type T) and ImmutableList<T> doesn’t care to fail softly when it gets an incompatible item type (note that IList isn’t generic). As, I discovered later, is the case with List<T>: it would return –1 when an incompatible type is passed whereas ImmutablList<T> would just crash.

 

However, I figured out that this is not a problem of ImmutableList<T> but of rather poor implementation of ComboBox in Windows Store (and perhaps of other similar types). Now, to make it worse, there are no sources for Windows Store ComboBox since it is a C++ dude and is virtually unfixable in the time I’d need the fix if I were to report the error somehow.

So the only solution for the time being is to switch to List<T> and avoid ImmutableList<T> even though it doesn’t mutate ever.

You’ve been warned!

 

Here is the repro code, just create a Windows Store app, get ImmutablCollections from NuGet and paste this xaml:

<ComboBox x:Name="combo" VerticalAlignment="Center" FontSize="70" Width="500"
           SelectedValue="{Binding ItemId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Id">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

and this codebehind:

public sealed partial class MainPage : Page
    {    
        Tubo tubo;
        public MainPage()
        {
            this.InitializeComponent();
            List<Item> items = Enumerable.Range(1, 20)
                 .Select(i => new Item { Id = i, Text = i.ToString() }).ToList();
            tubo = new Tubo();
            tubo.ItemId = 5;
            DataContext = tubo;

            combo.ItemsSource = items.ToImmutableList();
        }
    }

public class Item
{
    public int Id { get; set; }
    public string Text { get; set; }
}

public class Tubo
{
    public int ItemId { get; set; }
}
Update: I've checked with Windows 10 preview and VS2015CTP and the same bug is still there. Yuck.

Getting proper OpenGL driver for older AMD(ex. ATI) graphics cards on Windows 8

I have a not so new laptop that features ATI Radeon HD 3650 Mobility graphics cards. Which is quite fine for the usual tasks. According to AMD website it features OpenGL 3.2 which is, again, good enough. Nothing spectacular but fine.

Lately I’ve upgraded it to a SSD disk and at the same time I did a fresh Windows 8 install (previously it was Windows 7). Everything worked out very well. The laptop is usable again and quite fast now. Yesterday I tried to experiment with MonoGame, an open source implementation of, now legacy, XNA Framework – the framework that was supposed to run everywhere but Microsoft ditched it for some reason. Anyway, I’ve tried to run a sample MonoGame application and immediately faced a problem. First it was throwing an exception that OpenAL.dll is missing. Odd. I’ve found a standalone installation for OpenAL but the I run into another, more descriptive problem, something like: can’t find entry point for ‘glBindFramebuffer’ in OpenGL32.dll. That basically says that I had a pre-OpenGL 2.0 installed (MonoGame uses OpenTK which in turn requires minimum 2.0 version of OpenGL). How is that possible?

From what I understand the situation is that AMD isn’t supporting the Radeon Mobility HD 3xxx with Windows 8 and hence it doesn’t provide OpenGL drivers. So everything falls back to Microsoft provided OpenGL 1.1. That is nicely shown using GPU Caps Viewer application. This is ever more surprising because we had proper OpenGL drivers for it under Windows 7. If it was a desktop machine I’d consider changing the graphics card but that’s just not possible on the laptop. And I wasn’t quite happy to buy a newer laptop just for that, even more so because my laptop is doing just fine.

The solution

The solution is to install the latest drivers for Windows 7 manually. It is actually quick, easy and it works. You’ll find the procedure in Make Your Old Graphics Drivers Work in Windows 8article on Lockergnome. The only differences from article are that just right clicking on INF file doesn’t work nor the INF file is named exactly like the one in the article – it has higher number, probably because it is a newer one. Instead of the right click->install, which didn’t work, I had to go to Computer->right click->Manage->Device Manager->Display adapters->ATI Mobility Radeon HD 3650->right click->Properties->Driver->Update Driver->Browser my computer for driver software->Let me pick from a list of device drivers on my computer->Select proper INF file.

And voila – now I have OpenGL 3.3 support and MonoGame runs like a charm. Happy OpenGLing!