Saturday, July 11, 2009

Risk Map in Silverlight 2

As I mentioned in a previous post, I have reworked the USA map project to represent the map in the game of Risk.



The above image shows how the XAML is defined. The XAML is based on the SVG file found here. Once the project is ran, each country (both its inner and outer polygons) are entered into a data graph, similar to the one I used for the USA Map, with just a few improvements.

This demo, when ran, assigns each country to a player and assumes that you are the Green player. If you click on a country that is bordered with bright green, its border will turn black and all enemy held countries' borders will turn white. This shows what nations are available to attack.



If a programmer had a risk game play engine, this silverlight front-end will work quite well for you. The complete project can be downloaded here.

Tuesday, July 7, 2009

Dropthings - The good ideas and the bad

In a previous post I talked about my first impressions of the Dropthings project. Here I will talk about some of the ideas that I really liked in the Dropthings project, what ideas I will take away for my own project and the ideas that I thought were great but did not fit with my exact needs. And, at the very end I may add a few comments on another bad idea contained in the Dropthings project.

First I like the idea of not directly loading the widgets onto the page but instead having a common container where you load the widget, then the common container [lets call it the WidgetContainer :-)], is loaded on to the page. Here is a mockup of my version of the WidgetContainer user control:



The Dropthings project and my project save the widget information in two tables, the Widget table where all the default information about the widget is stored and the WidgetInstance table where the user specific widget information is stored. Since my requirements are that no controls are loaded until the user logs in, the entire generic user system in Dropthings, though cool, is not needed in my application.

So, after login, the process of loading the page is as simple as looping through the returned records and creating an instance of each widget inside its host container.

Lastly I would like to talk about the use of LINQ in the Dropthings project. Now I am not a huge advocate of LINQ, but there are times when it is the only tool that can solve the problem at hand, and I love it for that. What I do not like is that it:
A: Is database specific. Try running LINQ on Oracle or DB2 without purchasing third party plug-in. Sorry, cannot be done.
B: Unless it is watched very closely, the implementers of LINQ cross the data/rules boundary. In Dropthings you find LINQ commands everywhere. If you wanted to roll the Dropthings project out with an Oracle or DB2 back end, you would have a monumental time replacing all the Data access.

So, if the Dropthings project were not so tightly coupled with the data layer and workflow, I think (just my opinion) that the entire system would have benefited.

Thursday, July 2, 2009

Which UpdatePanel caused the Post?

Now that is a question! And the answer tool me nearly a day to discover. (OK, all of you that know the answer, stop snickering. I'm just learning the ASP.NET AJAX model)

After many dead ends, here is the key to finding what UpdatePanel caused the Post:
ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID

This returns the actual element ID that forced the Post. How does this help? Well, any post that originated in a UpdatePanel would be from a child control. So, if you walk up the control tree and find a UpdatePanel, you will have the UpdatePanel that caused the Post.

private UpdatePanel GetUpdatePanelThatCausedPostback()
{
var c = Page.FindControl(ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID);

while (c != null && !(c is UpdatePanel)) { c = c.Parent; }

if (c != null) return (c as UpdatePanel);
else return null;
}


Here we get the control that actually fired the Post and then we walk up the control tree, one by one, until we are either past the top (null) or we have found an UpdatePanel.

Then we simply either return the newly found UpdatePaenl or we return null.