<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d13405220\x26blogName\x3dPavan+Podila\x27s+Blog\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://pavanpodila.blogspot.com/search\x26blogLocale\x3den_US\x26v\x3d2\x26homepageUrl\x3dhttp://pavanpodila.blogspot.com/\x26vt\x3d7258010184004836690', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

Sunday, February 26, 2006

Flipping tile colors

Over the last few days I have spent a great deal of time creating/polishing the Polarium clone. As I kept adding more features, my design had to undergo some changes. With refactoring I was able to maintain the sanity during development. The whole exercise was to learn more about WPF and some of the APIs.

An interesting feature I added yesterday was the ability to flip the tile colors (White->Black, Black->White). Although this is not technically difficult, it is useful while solving puzzles. Consider the puzzle shown below:




As you start to solve this puzzle you will have to take a few moments to think about making your first move. It appears like there are more black tiles than white and in some ways this contrast makes it difficult to decide where to start. Now have a look at the same puzzle with the tile colors reversed (White -> Black, Black -> White).



The puzzle has suddenly become much more manageable. Now the contrast is much better and we can clearly see the pattern. For some puzzles, flipping the tile colors can greatly change our perception of difficulty of the puzzle. The idea is to solve the puzzle and this is one feature that can help you do that!

Implementation problems

An interesting bug I found while implementing this feature was when I would switch the ControlTemplate for the tiles from WhiteTileTemplate to BlackTileTemplate and vice versa. For doing that I would simply assign the template as:

string template = "GrayTileTemplate";

if (tile.Color == TileColor.Black)
{
template = "BlackTileTemplate";
}
else if (tile.Color == TileColor.White)
{
template = "WhiteTileTemplate";
}

b.Template = FindResource(template) as ControlTemplate;


However only assigning the template does not always set the template! It works for the first time but any subsequent template changes does not update the VisualTree. This came as a surprise to me since that is what I would expect with the previous code. After digging some time into the documentation, I found the FrameworkElement.ApplyTemplate() API. The docs say the following:

Builds the current template's visual tree if necessary, and returns a value indicating whether the visual tree was rebuilt by this call.

So my solution was to just call ApplyTemplate() following the template setting.

b.Template = FindResource(template) as ControlTemplate;
b.ApplyTemplate();

I think this is bad design. The setter of the Template property should have done this. I am not sure what is the rationale behind this approach.

Download Source and Binaries (v2.2)