tag:blogger.com,1999:blog-66725605041417344072023-11-16T09:44:49.770-06:00Taking Dot Net "Old School"Playing with old ideas/concepts using the newest tools!Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.comBlogger74125tag:blogger.com,1999:blog-6672560504141734407.post-62146827895063298502019-08-27T04:56:00.001-05:002019-08-27T04:56:51.952-05:00Loading an image into an ImageButton from an EmbeddedResource<p><font size="1">Sad, but this took me awhile to figure out. A lot of the examples on the web are incorrect so it took quite a bit of thrashing to figure this simple thing out.</font></p><p><font size="1">The way to load an image into an ImageButton from an EmbeddedResource is to of course add an image to your project and mark it as EmbeddedResource. </font></p><p><font size="1">The next step is to determine the “path” to this resource. If the project name is “Project” and the folder you added your image to is named “Folder” and the image is named “Image.png” then the “path” to this image is "Project.Folder.Image.png”</font></p><p><font size="1">Then it is a simple process to use the static class ImageSource, like this:</font></p><pre style="background: white; color: black; font-family: consolas; font-size: 16px;"><span style="color: rgb(43, 145, 175);">ImageSource</span>.FromResource(<span style="color: rgb(163, 21, 21);">"Project.Folder.Image.png"</span>)
</pre>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-67171579153360862532019-08-25T09:54:00.001-05:002019-08-25T10:01:02.386-05:00Back in the (programming) saddle again!<p><font size="1">I never thought it could happen to me. I had publicly said, many times, that it just could never happen to me because it was such an integral part of my life, but it did.</font></p><p><font size="1">I burnt out on programming.</font></p><p><font size="1">I was stretched just too thin. My personal life was falling apart from dealing with my wife’s two year losing battle with cancer. I worked for, what some people would call, one of the best companies in the world: CSG International. They allowed me to work first from home and then later from the hospital as I cared for my wife. They bent over backwards to help me through this most painful of times. But, in the end I realized that I just could not write code anymore. I was totally burnt out. So, I did the only honorable think I could do .. I resigned.</font></p><p><font size="1">And, in my personal life, I was completely drained. After my wife passed, I just needed to escape. so I did.</font></p><p><p><font size="1">To the Philippines. I have now remarried to a beautiful Filipina and I now have a … DAUGHTER!</font></p><p><font size="1">When I moved, my sister said that I would be back at the keyboard pounding out code in no time. Knowing how much programming meant to me, she predicted it would only take two months.</font></p><p><font size="1">Eighteen months later …</font></p><p><font size="1">I am finally getting the itch to program again and I have started to learn how to write mobile apps using the Xamarin platform. I have already hit some snags that were not the easiest to unravel so I figured I would share my journey with the world.</font></p><p><font size="1">Programming, I missed you! Welcome back!</font></p><p><br></p><p><font size="5"><br></font></p></p>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-9674347617734593812016-08-30T19:58:00.000-05:002016-08-30T19:58:00.194-05:00Changing the ZIndex of a XAML Element using a Storyboard<p><br><font size="3">One of my current projects has two XAML elements moving in 3D and as the second element eclipsed the first element the ZIndex had to be changed so the second element would now appear in front of the first. </font></p> <p><font size="3">Lots of searching later (and quite a few articles saying that it was not possible) I came up with a XAML based Storyboard that worked, but since I needed to build the Storyboard programmatically, I needed to convert it to C# code.</font></p> <p><font size="3">This is what I came up with:</font></p> <div style="font-size: 10pt; border-top: #000080 1px solid; font-family: consolas, 'Courier New', courier, monospace; border-right: #000080 1px solid; border-bottom: #000080 1px solid; color: #000; border-left: #000080 1px solid"> <div style="font-family: verdana, tahoma, arial, sans-serif; background: #000080; font-weight: bold; color: #fff; padding-bottom: 2px; padding-top: 2px; padding-left: 5px; padding-right: 5px">Code Snippet – CreateZIndexStoryboard</div> <div style="overflow: auto; background: #f3f3f3; color: #000000; max-height: 500px"> <ol style="background: #ffffff; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 4em; padding-right: 0px" start="108"> <li><span style="color: #0000ff">private</span> <span style="color: #2b91af">Storyboard</span> CreateZIndexStoryboard(<span style="color: #2b91af">FrameworkElement</span> fromElement, <span style="color: #0000ff">int</span> newZIndex) <li style="background: #f3f3f3">{ <li> <span style="color: #0000ff">var</span> myZIndexStoryboard = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Storyboard</span>(); <li style="background: #f3f3f3"> <span style="color: #0000ff">var</span> myZIndexAnimation = <span style="color: #0000ff">new</span> <span style="color: #2b91af">ObjectAnimationUsingKeyFrames</span>(); <li> <span style="color: #0000ff">var</span> myZIndexKeyFrame = <span style="color: #0000ff">new</span> <span style="color: #2b91af">DiscreteObjectKeyFrame</span> <li style="background: #f3f3f3"> { <li> Value = newZIndex, <li style="background: #f3f3f3"> KeyTime = <span style="color: #2b91af">TimeSpan</span>.FromMilliseconds(AnimationLength/2) <li> }; <li style="background: #f3f3f3"> <li> myZIndexAnimation.KeyFrames.Add(myZIndexKeyFrame); <li style="background: #f3f3f3"> <li> myZIndexStoryboard.Children.Add(myZIndexAnimation); <li style="background: #f3f3f3"> <li> <span style="color: #2b91af">Storyboard</span>.SetTarget(myZIndexAnimation, fromElement); <li style="background: #f3f3f3"> <span style="color: #2b91af">Storyboard</span>.SetTargetProperty(myZIndexAnimation, <span style="color: #a31515">"(Canvas.ZIndex)"</span>); <li> <li style="background: #f3f3f3"> <span style="color: #0000ff">return</span> myZIndexStoryboard; <li>} </li></ol></div></div> <p><font size="3">One of the main points of difference between Silverlight and Windows Universal XAML is that setting the target property on the storyboard, ie. <font face="Courier New">Storyboard.SetTargetProperty </font><font face="Arial">is that in silverlight you would set the path to the property by creating a new PropertyPath object. With Windows Universal XAML you using a binding to a property using a string with binding syntax.</font></font></p>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-84160561316178039202016-08-24T18:41:00.000-05:002016-08-27T12:25:26.258-05:00How do you recognise good programmers if you’re a business guy?<p><br><font size="3"><font color="#ff0000">[ Disclaimer: Many years ago I found an article out on the interwebs that described how to recognize a good programmer for the viewpoint of a non-programmer. Later, in 2012, I wanted to reference it in a blog post and during my search I ran across</font><font color="#0000ff"> </font></font><a href="https://groups.google.com/forum/#!topic/comp.databases.pick/aCazTFezMKU"><font color="#0000ff" size="3">[this]</font></a><font size="3"> <font color="#ff0000">post where the commenter compared programming to diesel mechanics and then tried to show that the “bad” programmer was the one that *HE* would hire. I wrote</font><font color="#0000ff"> </font><a href="http://oldschooldotnet.blogspot.com/2012/02/im-58-out-of-6-programmer.html"><font color="#0000ff">[</font></a><a href="http://oldschooldotnet.blogspot.com/2012/02/im-58-out-of-6-programmer.html"><font color="#0000ff">this</font></a><a href="http://oldschooldotnet.blogspot.com/2012/02/im-58-out-of-6-programmer.html"><font color="#0000ff">]</font></a></font><a href="http://oldschooldotnet.blogspot.com/2012/02/im-58-out-of-6-programmer.html"><font style="background-color: #ffff00"></font></a><font size="3"> <font color="#ff0000">blog post with my take on his comparison. </font></font></p> <p><font color="#ff0000" size="3">Unfortunately the original article is no longer available so I am posting a copy of it here so that the original authors wisdom will not be lost.</font></p> <p><font color="#ff0000" size="3">Remember, I did NOT write this.]</font></p> <p><font size="3">It’s not as easy as it sounds. CV experience is only of limited use here, because great programmers don’t always have the “official” experience to demonstrate that they’re great. In fact, a lot of that CV experience can be misleading. Yet there are a number of subtle cues that you can get, even from the CV, to figure out whether someone’s a great programmer. </font> <p><font size="3">I consider myself to be a pretty good programmer. At the same time, I’ve spent a fair amount of time on the business side of the fence, filtering technical CVs for projects, interviewing people, etc. Thanks to this, I think I have a bit of experience in recognising good programmers, and I want to share it in this article, in the hope that it may help other “business guys” to recognise good programmers. And, who knows, perhaps some programmers who have the potential to be good but haven’t really exploited this can also read this and realise what they need to do to become good (although, as I’ll argue, that’s definitely not accessible to all programmers!). </font> <p><font size="3">In his article The 18 mistakes that kill startups, Paul Graham makes the following point: </font> <p><font size="3">“… what killed most of the startups in the e-commerce business back in the 90s, it was bad programmers. A lot of those companies were started by business guys who thought the way startups worked was that you had some clever idea and then hired programmers to implement it. That’s actually much harder than it sounds—almost impossibly hard in fact—because business guys can’t tell which are the good programmers. They don’t even get a shot at the best ones, because no one really good wants a job implementing the vision of a business guy. </font> <p><font size="3">In practice what happens is that the business guys choose people they think are good programmers (it says here on his resume that he’s a Microsoft Certified Developer) but who aren’t. Then they’re mystified to find that their startup lumbers along like a World War II bomber while their competitors scream past like jet fighters. This kind of startup is in the same position as a big company, but without the advantages. </font> <p><font size="3">So how do you pick good programmers if you’re not a programmer? I don’t think there’s an answer. I was about to say you’d have to find a good programmer to help you hire people. But if you can’t recognize good programmers, how would you even do that?” </font> <p><font size="3">I disagree with Mr. Graham on this one. I think there are a number of very strong indicators of a “good programmer” (and, conversely, strong indicators of a “not-so-good programmer”) that even a business guy can recognise. I’ll summarise some key indicators and counter-indicators in a list at the end of the article.</font></p> <p><font size="3"><em><strong><u>#1 : Passion</u></strong></em> </font></p> <p><font size="3">In my corporate experience, I met a kind of technical guy I’d never met before: the career programmer. This is a person who’s doing IT because they think it’s a good career. They don’t do any programming in their spare time. They’re shocked when they find out I have a LAN and 3 computers at home. They just do it at work. They don’t learn new stuff unless sent on a training program (or motivated by the need to get a job that requires that technology). They do “programming” as a day job. They don’t really want to talk about it outside of work. When they do, they talk with a distinctive lack of enthusiasm. Basically, they lack passion. </font> <p><font size="3">I believe that good developers are always passionate about programming. Good developers would do some programming even if they weren’t being paid for it. Good programmers will have a tendency to talk your ear off about some technical detail of what they’re working on (but while clearly believing, sincerely, that what they’re talking about is really worth talking about). Some people might see that as maladapted social skills (which it is), but if you want to recognise a good developer, this passion for what they’re doing at the expense of social smoothness is a very strong indicator. Can you get this guy to excitedly chat up a technology that he’s using, for a whole half hour, without losing steam? Then you might be onto a winner. </font> <p><font size="3"><strong><em><u>#2 : Self-teaching and love of learning</u></em></strong> </font> <p><font size="3">Programming is the ultimate moving target. Not a year goes by without some new technology robbing an old, established standard blind and changing half the development universe. This is not to say that all good programmers pick up these changes and ride the bleeding edge. However, there’s a class of programmers that will never, ever pick up a new technology unless forced to, because they don’t like learning new stuff. These programmers will typically have learnt programming at university, and expect to get by on whatever skills they picked up there, plus whatever courses their company is willing to send them on. </font> <p><font size="3">If you’re thinking of hiring someone as a programmer, and he ever utters the words “I can work with that, just send me on a training course for a week and I’ll be good at it”, don’t hire that guy. A good programmer doesn’t need a training course to learn a new technology. In fact, the great programmer will be the one talking your ear off about a new technology that you haven’t even heard of, explaining to you why you must use it in your business, even if none of your staff knows how to use it. Even if it’s a technology he doesn’t know how to use yet. </font> <p><font size="3"><strong><em><u>#3 : Intelligence</u></em></strong> </font> <p><font size="3">Some business people assume that lack of social tact and lack of intelligence are the same. Actually, intelligence has several facets, and emotional/social intelligence is only one of them. Good programmers aren’t dumb. Ever. In fact, good programmers are usually amongst the smartest people you know. Many of them will actually have pretty good social skills too. The cliché of the programmer who’s incapable of having a conversation is just that - a cliché. I’ve been to a few meetings of the London Ruby User Group and I can say that with only a very few exceptions, most people there are smart, talkative, sociable, have varied interests, etc. You wouldn’t look at them chattering away in the pub and think “what a bunch of geeks!” - at least until you approach a group and realise they’re talking about the best way to design a RESTful application with a heavy UI frontend. </font> <p><font size="3">This doesn’t mean that they’ll all feel comfortable in every social context. But it does mean that if the context is comfortable and non-threatening enough, you’ll be able to have as great a conversation with them as you would with the most “socially enabled” people (perhaps better, since most good programmers I know like their conversation to revolve around actually useful topics, rather than just inane banter). </font> <p><font size="3">Don’t ever hire a dumb person thinking they’re a good developer. They’re not. If you can’t have a great conversation with them in a relaxed social context, they’re very likely not a good programmer. On the other hand, anyone who’s clearly very smart at the very least has a strong potential to be a good or great programmer.<br><br><strong><em><u>#4 : Hidden experience</u></em></strong> </font></p> <p><font size="3">This is correlated with the “Passion” point, but it is such a strong indicator that I’d like to emphasise it with its own point. </font> <p><font size="3">I started programming when I was about 9, on a Commodore 64. I then migrated onto the PC, did some Pascal. When I was 14 I wrote a raycasting engine in C and Assembler, spent a large amount of time playing with cool graphic effects that you could get your computer to do by messing directly with the video card. This was what I call my “cocoon stage”. When I entered that stage, I was a mediocre programmer, and lacked the confidence to do anything really complicated. When I finished it, I had gained that confidence. I knew that I could code pretty much anything so long as I put my mind to it. </font> <p><font size="3">Has that ever appeared on my CV? Nope. </font> <p><font size="3">I strongly believe that most good programmers will have a hidden iceberg or two like this that doesn’t appear on their CV or profile. Something they think isn’t really relevant, because it’s not “proper experience”, but which actually represents an awesome accomplishment. A good question to ask a potential “good programmer” in an interview would be “can you tell me about a personal project - even or especially one that’s completely irrelevant - that you did in your spare time, and that’s not on your CV?” If they can’t (unless their CV is 20 pages long), they’re probably not a good programmer. Even a programmer with an exhaustive CV will have some significant projects that are missing from there. </font> <p><font size="3"><strong><em><u>#5 : Variety of technologies</u></em></strong> </font> <p><font size="3">This one’s pretty simple. Because of the love of learning and toying with new technologies that comes with the package of being a “good programmer”, it’s inevitable that any “good programmer” over the age of 22 will be fluent in a dozen different technologies. They can’t help it. Learning a new technology is one of the most fun things a programmer with any passion can do. So they’ll do it all the time, and accumulate a portfolio of things they’ve “played around with”. They may not be experts at all of them, but all decent programmers will be fluent in a large inventory of unrelated technologies. </font> <p><font size="3">That “unrelated” bit is the subtle twist. Every half-decent java programmer will be able to list a set of technologies like “Java, J2EE, Ant, XML, SQL, Hibernate, Spring, Struts, EJB, Shell scripting”, etc.. But those are all part of the same technology stack, all directly related to each other. This is possibly hard to recognise for non-programmers, but it is possible to tell whether their technology stack is varied by talking to them about it, and asking them how the different technologies they know relate to each other. Over-specialisation in a single technology stack is an indicator of a not-so-good programmer. </font> <p><font size="3">Finally, if some of those technologies are at the bleeding edge, that’s a good positive indicator. For instance, today (November 2007), knowledge of Merb, Flex, RSpec, HAML, UJS, and many others… Please note that these are fairly closely related technologies, so in a couple of years, someone who knows all these will be equivalent to someone familiar with the Java stack listed in the previous paragraph. </font> <p><font size="3">Update: As a clarification to this point, there’s in fact two indicators here: variety and bleeding edge. Those are separate indicators. A good variety of technologies across a period of time is a positive indicator, whether or not the technologies are bleeding edge. And bleeding edge technologies are a positive indicator, whether or not there’s a variety of them. </font> <p><font size="3"><strong><em><u>#6 : Formal qualifications</u></em></strong> </font> <p><font size="3">This is more a of non-indicator than a counter-indicator. The key point to outline here is that formal qualifications don’t mean squat when you’re trying to recognise a good programmer. Many good programmers will have a degree in Computer Science. Many won’t. Certifications, like MCSE or SCJP or the like, don’t mean anything either. These are designed to be accessible and desirable to all. The only thing they indicate is a certain level of knowledge of a technology. They’re safeguards that allow technology recruitment people in large corporations to know “ok, this guy knows java, he’s got a certification to prove it” without having to interview them. </font> <p><font size="3">If you’re hiring for a small business, or you need really smart developers for a crack team that will implement agile development in your enterprise, you should disregard most formal qualifications as noise. They really don’t tell you very much about whether the programmer is good. Similarly, disregard age. Some programmers are awesome at 18. Others are awesome at 40. You can’t base your decisions about programmer quality on age (though you might decide to hire people around a certain age to have a better fit in the company; please do note that age discrimination is illegal in most countries!). </font> <p><font size="3">As a final note to this, in my experience most average or poor programmers start programming at university, for their Computer Science course. Most good programmers started programming long before, and the degree was just a natural continuation of their hobby. If your potential programmer didn’t do any programming before university, and all his experience starts when she got her first job, she’s probably not a good programmer. </font> <p><font size="3"><strong><em><u>Disclaimer </u></em></strong></font> <p><font size="3">None of the indicators above or below are sure-fire indicators. You will find great programmers who break some of those moulds. However, my view is, you’ll rarely find a great programmer that breaks all of them. Similarly, you may find poor programmers that meet (or appear to meet) some of these criteria. But I do strongly believe that the more of these criteria a programmer meets, the more likely they are to be one of those elusive “good programmers” that, as a business guy, you need to partner with.<br><br>The criteria in bullets </font></p> <p><font size="3">So, in summary, here are some indicators and counter-indicators that should help you recognise a good programmer. </font> <p><font size="3"><u>Positive indicators:</u> </font> <ul> <li><font size="3"> Passionate about technology</font> <li><font size="3"> Programs as a hobby</font> <li><font size="3"> Will talk your ear off on a technical subject if encouraged</font> <li><font size="3"> Significant (and often numerous) personal side-projects over the years</font> <li><font size="3"> Learns new technologies on his/her own</font> <li><font size="3"> Opinionated about which technologies are better for various usages</font> <li><font size="3"> Very uncomfortable about the idea of working with a technology he "doesn't believe to be right”</font> <li><font size="3"> Clearly smart, can have great conversations on a variety of topics</font> <li><font size="3"> Started programming long before university/work</font> <li><font size="3"> Has some hidden “icebergs”, large personal projects under the CV radar</font> <li><font size="3"> Knowledge of a large variety of unrelated technologies (may not be on CV) </font> <li><font size="3"><u>Negative indicators:</u> </font> <li><font size="3"> Programming is a day job</font> <li><font size="3"> Don’t really want to “talk shop”, even when encouraged to</font> <li><font size="3"> Learns new technologies in company-sponsored courses</font> <li><font size="3"> Happy to work with whatever technology you’ve picked, “all technologies are good"</font> <li><font size="3"> Doesn’t seem too smart</font> <li><font size="3"> Started programming at university</font> <li><font size="3"> All programming experience is on the CV</font> <li><font size="3"> Focused mainly on one or two technology stacks (e.g. everything to do with developing a java application), with no experience outside of it </font></li></ul> <p><font size="3">I hope these help. Let me know below if you have any comments, or anything to add to them! </font></p> <p><font size="3">Thanks for reading.</font></p>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-82960018850898003562016-08-21T17:57:00.001-05:002016-08-21T17:57:41.377-05:00It’s been a while, but I’m back.<p>When I started this blog, way back in 2008, my main goal was to record and share my experiences as I grew as a programmer. I didn’t want to rehash the same information that you got from a hundred other sources. Instead I wanted to show the unique parts of my eternal journey to be a better programmer.</p> <p>During my three year hiatus I grew a lot, but I would put quite a bit of it under the heading of “Everyone else has been there, done that” and I could not really justify wasting your time reading such drivel. Plus, lots of personal “stuff” happened, such as the death of my Mother-in-law and last years diagnosis of my wife’s cancer.</p> <p>So, I expect to start adding new content soon. Prepare yourself. You have been warned.</p>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-82739564097416644992013-11-15T12:00:00.000-06:002013-11-15T12:00:00.590-06:00Creating XAML hexagons without using a PATH element<p>I was recently working on a small Windows Phone 8 app that needed some tessellated (tiled) hexagons and after searching the web for a simple solution, I did not find what I wanted. </p> <p>All of the solutions involved drawing the hexagon using drawing primitives such as the PATH element. I wanted a “simpler” solution. I wanted a Grid based solution, and here it is.</p> <p>To start with I needed to know two semi-basic points about hexagons: what is the ratio of height to width, and (with the hex “standing” on one of its flat sides) what is the the ratio between the horizontal length of the flat and the horizontal distance from the end of the flat side to the edge of the hexagon. (Boy that is harder to write than it is to just see it)</p> <p>I found both pieces of information at: <a href="http://hexnet.org/content/hexagonal-geometry" target="_blank">Hexnet</a></p> <p>Hexnet shows that if the length of one side of a hex has a length of 1, then the overall width is 2 and the height of the hexagon is √3 (approx. 1.73). So, if we were to build this in a grid, we would have a single hexagon take up 6 cells (2 rows and 3 columns) and our two critical semi-basic points are: √3 to 2 and 1 to .5.</p> <p>If we wanted a hexagon with an overall width of 200px (200 times our example above), our grid would be defined as:</p> <div class="csharpcode"><pre class="alt"><span class="lnum"> 1: </span><Grid x:Name=<span class="str">"LayoutRoot"</span> Background=<span class="str">"White"</span> Width=<span class="str">"200"</span> Height=<span class="str">"173"</span>></pre><pre><span class="lnum"> 2: </span> <Grid.ColumnDefinitions></pre><pre class="alt"><span class="lnum"> 3: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 4: </span> <ColumnDefinition Width=<span class="str">"2*"</span>></ColumnDefinition></pre><pre class="alt"><span class="lnum"> 5: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 6: </span> </Grid.ColumnDefinitions></pre><pre class="alt"><span class="lnum"> 7: </span> <Grid.RowDefinitions></pre><pre><span class="lnum"> 8: </span> <RowDefinition></RowDefinition></pre><pre class="alt"><span class="lnum"> 9: </span> <RowDefinition></RowDefinition></pre><pre><span class="lnum"> 10: </span> </Grid.RowDefinitions></pre><pre class="alt"><span class="lnum"> 11: </span></Grid></pre></div><br /><style type="text/css">.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }<br /></style><br /><br /><p>if you look at this grid with gridlines on, you get:</p><br /><p><a href="http://lh6.ggpht.com/-Vd6ngYm02-Y/UoPzeePFIBI/AAAAAAAAAHM/TreeyTCKeJk/s1600-h/image2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-IlprrAS3Vfc/UoPzfG3DRAI/AAAAAAAAAHU/jZElv4urSXI/image_thumb.png?imgmax=800" width="211" height="184"></a></p><br /><br /><p>Now from here we can either create a outline of a hexagon using 6 line objects, create a solid hexagon using 3 rectangle objects or combine both for an outlined solid color hexagon.</p><br /><p>“Wait!”, you say. “I can see the six lines making up the outline of a hexagon, but how could you do a solid color hexagon with three squares?”</p><br /><p>Well, I’m glad you asked. If you fill the center column with a rectangle, that’s one. If you make a copy but rotate it 60 degrees using the center as the pivot point and make a third and rotate it –60 degrees then you have your solid color hexagon.</p><br /><p>And, if you just start repeating the second and third columns when you add columns, you can start to create a grid full of tessellated (tiled) hexagons, just like I did in this image.</p><br /><p><a href="http://lh4.ggpht.com/-YiuOywAUtHw/UoPzfnHOlwI/AAAAAAAAAHc/dehJg7oXcMI/s1600-h/image%25255B3%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-s5FU86FHwZc/UoPzgGYM2mI/AAAAAAAAAHg/jmCyoLVaDP0/image_thumb%25255B1%25255D.png?imgmax=800" width="244" height="182"></a></p><br /><p>And here is the complete xaml I used to create the above image (From this code it was simple to extract rules that I used to create large fields of tessellated (tiled) hexagons in code):</p><br /><div class="csharpcode"><pre class="alt"><span class="lnum"> 1: </span><UserControl x:Class=<span class="str">"Hexagon.MainPage"</span></pre><pre><span class="lnum"> 2: </span> xmlns=<span class="str">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre><pre class="alt"><span class="lnum"> 3: </span> xmlns:x=<span class="str">"http://schemas.microsoft.com/winfx/2006/xaml"</span></pre><pre><span class="lnum"> 4: </span> xmlns:d=<span class="str">"http://schemas.microsoft.com/expression/blend/2008"</span></pre><pre class="alt"><span class="lnum"> 5: </span> xmlns:mc=<span class="str">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre><pre><span class="lnum"> 6: </span> mc:Ignorable=<span class="str">"d"</span></pre><pre class="alt"><span class="lnum"> 7: </span> d:DesignHeight=<span class="str">"346"</span> d:DesignWidth=<span class="str">"500"</span>></pre><pre><span class="lnum"> 8: </span> <Viewbox Stretch=<span class="str">"Uniform"</span>></pre><pre class="alt"><span class="lnum"> 9: </span> <Grid x:Name=<span class="str">"LayoutRoot"</span> Background=<span class="str">"White"</span> Width=<span class="str">"500"</span> Height=<span class="str">"346"</span> Margin=<span class="str">"50"</span>></pre><pre><span class="lnum"> 10: </span> <Grid.ColumnDefinitions></pre><pre class="alt"><span class="lnum"> 11: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 12: </span> <ColumnDefinition Width=<span class="str">"2*"</span>></ColumnDefinition></pre><pre class="alt"><span class="lnum"> 13: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 14: </span> <ColumnDefinition Width=<span class="str">"2*"</span>></ColumnDefinition></pre><pre class="alt"><span class="lnum"> 15: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 16: </span> <ColumnDefinition Width=<span class="str">"2*"</span>></ColumnDefinition></pre><pre class="alt"><span class="lnum"> 17: </span> <ColumnDefinition Width=<span class="str">"*"</span>></ColumnDefinition></pre><pre><span class="lnum"> 18: </span> </Grid.ColumnDefinitions></pre><pre class="alt"><span class="lnum"> 19: </span> <Grid.RowDefinitions></pre><pre><span class="lnum"> 20: </span> <RowDefinition></RowDefinition></pre><pre class="alt"><span class="lnum"> 21: </span> <RowDefinition></RowDefinition></pre><pre><span class="lnum"> 22: </span> <RowDefinition></RowDefinition></pre><pre class="alt"><span class="lnum"> 23: </span> <RowDefinition></RowDefinition></pre><pre><span class="lnum"> 24: </span> </Grid.RowDefinitions></pre><pre class="alt"><span class="lnum"> 25: </span> <Rectangle Fill=<span class="str">"Pink"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></Rectangle></pre><pre><span class="lnum"> 26: </span> <Rectangle Fill=<span class="str">"Pink"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre class="alt"><span class="lnum"> 27: </span> <Rectangle.RenderTransform></pre><pre><span class="lnum"> 28: </span> <RotateTransform Angle=<span class="str">"-60"</span> /></pre><pre class="alt"><span class="lnum"> 29: </span> </Rectangle.RenderTransform></pre><pre><span class="lnum"> 30: </span> </Rectangle></pre><pre class="alt"><span class="lnum"> 31: </span> <Rectangle Fill=<span class="str">"Pink"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre><span class="lnum"> 32: </span> <Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 33: </span> <RotateTransform Angle=<span class="str">"60"</span> /></pre><pre><span class="lnum"> 34: </span> </Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 35: </span> </Rectangle></pre><pre><span class="lnum"> 36: </span> <Rectangle Fill=<span class="str">"Aquamarine"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"3"</span> Grid.Row=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></Rectangle></pre><pre class="alt"><span class="lnum"> 37: </span> <Rectangle Fill=<span class="str">"Aquamarine"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"3"</span> Grid.Row=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre><span class="lnum"> 38: </span> <Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 39: </span> <RotateTransform Angle=<span class="str">"-60"</span> /></pre><pre><span class="lnum"> 40: </span> </Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 41: </span> </Rectangle></pre><pre><span class="lnum"> 42: </span> <Rectangle Fill=<span class="str">"Aquamarine"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"3"</span> Grid.Row=<span class="str">"1"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre class="alt"><span class="lnum"> 43: </span> <Rectangle.RenderTransform></pre><pre><span class="lnum"> 44: </span> <RotateTransform Angle=<span class="str">"60"</span> /></pre><pre class="alt"><span class="lnum"> 45: </span> </Rectangle.RenderTransform></pre><pre><span class="lnum"> 46: </span> </Rectangle></pre><pre class="alt"><span class="lnum"> 47: </span> <Rectangle Fill=<span class="str">"LightBlue"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></Rectangle></pre><pre><span class="lnum"> 48: </span> <Rectangle Fill=<span class="str">"LightBlue"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre class="alt"><span class="lnum"> 49: </span> <Rectangle.RenderTransform></pre><pre><span class="lnum"> 50: </span> <RotateTransform Angle=<span class="str">"-60"</span> /></pre><pre class="alt"><span class="lnum"> 51: </span> </Rectangle.RenderTransform></pre><pre><span class="lnum"> 52: </span> </Rectangle></pre><pre class="alt"><span class="lnum"> 53: </span> <Rectangle Fill=<span class="str">"LightBlue"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre><span class="lnum"> 54: </span> <Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 55: </span> <RotateTransform Angle=<span class="str">"60"</span> /></pre><pre><span class="lnum"> 56: </span> </Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 57: </span> </Rectangle></pre><pre><span class="lnum"> 58: </span> <Rectangle Fill=<span class="str">"LemonChiffon"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></Rectangle></pre><pre class="alt"><span class="lnum"> 59: </span> <Rectangle Fill=<span class="str">"LemonChiffon"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre><span class="lnum"> 60: </span> <Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 61: </span> <RotateTransform Angle=<span class="str">"-60"</span> /></pre><pre><span class="lnum"> 62: </span> </Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 63: </span> </Rectangle></pre><pre><span class="lnum"> 64: </span> <Rectangle Fill=<span class="str">"LemonChiffon"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"2"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre class="alt"><span class="lnum"> 65: </span> <Rectangle.RenderTransform></pre><pre><span class="lnum"> 66: </span> <RotateTransform Angle=<span class="str">"60"</span> /></pre><pre class="alt"><span class="lnum"> 67: </span> </Rectangle.RenderTransform></pre><pre><span class="lnum"> 68: </span> </Rectangle></pre><pre class="alt"><span class="lnum"> 69: </span> <Rectangle Fill=<span class="str">"Thistle"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"0"</span> Grid.RowSpan=<span class="str">"2"</span>></Rectangle></pre><pre><span class="lnum"> 70: </span> <Rectangle Fill=<span class="str">"Thistle"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"0"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre class="alt"><span class="lnum"> 71: </span> <Rectangle.RenderTransform></pre><pre><span class="lnum"> 72: </span> <RotateTransform Angle=<span class="str">"-60"</span> /></pre><pre class="alt"><span class="lnum"> 73: </span> </Rectangle.RenderTransform></pre><pre><span class="lnum"> 74: </span> </Rectangle></pre><pre class="alt"><span class="lnum"> 75: </span> <Rectangle Fill=<span class="str">"Thistle"</span> RenderTransformOrigin=<span class="str">"0.5, 0.5"</span> Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"0"</span> Grid.RowSpan=<span class="str">"2"</span>></pre><pre><span class="lnum"> 76: </span> <Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 77: </span> <RotateTransform Angle=<span class="str">"60"</span> /></pre><pre><span class="lnum"> 78: </span> </Rectangle.RenderTransform></pre><pre class="alt"><span class="lnum"> 79: </span> </Rectangle></pre><pre><span class="lnum"> 80: </span> <Line Grid.Column=<span class="str">"0"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 81: </span> <Line Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Top"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 82: </span> <Line Grid.Column=<span class="str">"2"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 83: </span> <Line Grid.Column=<span class="str">"0"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 84: </span> <Line Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Bottom"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 85: </span> <Line Grid.Column=<span class="str">"2"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 86: </span> <Line Grid.Column=<span class="str">"3"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Top"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 87: </span> <Line Grid.Column=<span class="str">"4"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 88: </span> <Line Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Top"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 89: </span> <Line Grid.Column=<span class="str">"6"</span> Grid.Row=<span class="str">"0"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 90: </span> <Line Grid.Column=<span class="str">"4"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 91: </span> <Line Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Bottom"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 92: </span> <Line Grid.Column=<span class="str">"6"</span> Grid.Row=<span class="str">"1"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 93: </span> <Line Grid.Column=<span class="str">"0"</span> Grid.Row=<span class="str">"2"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 94: </span> <Line Grid.Column=<span class="str">"2"</span> Grid.Row=<span class="str">"2"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 95: </span> <Line Grid.Column=<span class="str">"0"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 96: </span> <Line Grid.Column=<span class="str">"1"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Bottom"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 97: </span> <Line Grid.Column=<span class="str">"2"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 98: </span> <Line Grid.Column=<span class="str">"3"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Top"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 99: </span> <Line Grid.Column=<span class="str">"4"</span> Grid.Row=<span class="str">"2"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 100: </span> <Line Grid.Column=<span class="str">"6"</span> Grid.Row=<span class="str">"2"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 101: </span> <Line Grid.Column=<span class="str">"4"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"1"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 102: </span> <Line Grid.Column=<span class="str">"5"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"0"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> VerticalAlignment=<span class="str">"Bottom"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre class="alt"><span class="lnum"> 103: </span> <Line Grid.Column=<span class="str">"6"</span> Grid.Row=<span class="str">"3"</span> X1=<span class="str">"1"</span> Y1=<span class="str">"0"</span> X2=<span class="str">"0"</span> Y2=<span class="str">"1"</span> Margin=<span class="str">"-5 -5"</span> StrokeThickness=<span class="str">"10"</span> Stretch=<span class="str">"Fill"</span> Stroke=<span class="str">"Black"</span> StrokeEndLineCap=<span class="str">"Round"</span> StrokeStartLineCap=<span class="str">"Round"</span>></Line></pre><pre><span class="lnum"> 104: </span> </Grid></pre><pre class="alt"><span class="lnum"> 105: </span> </Viewbox></pre><pre><span class="lnum"> 106: </span></UserControl></pre></div><br /><style type="text/css">.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }<br /></style> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-56613573085359150082013-11-12T15:11:00.001-06:002013-11-12T15:11:05.219-06:00My adventures in Windows Phone 8 development<p>A couple of months ago, I attended VSLive in Redmond. While I was there I sat in on a session on Windows Phone 8 Development given by Nick Landry ( <a href="https://twitter.com/ActiveNick" target="_blank">@ActiveNick</a> ). </p> <p>Since then I’ve signed up for a Windows Phones Developers Account ( <a href="http://www.windowsphone.com/en-US/store/publishers?publisherId=Beer%2Band%2BPretzel%2BGames&appId=3d2b6abf-fdd6-43a8-b14d-99e7bb9294fb" target="_blank">Beer & Pretzel Games</a> ), a DVLUP.com account ( <a href="http://www.dvlup.com/saunderl#" target="_blank">My saunderl account</a> ) and have published 3 apps (Tic Tac Toe, Sudoku Challenge and Simple Lap Counter). None of these apps are going to set the world on fire, but it is a start and I’ve got a list of about twenty other apps and games I want to write.</p> <p>So, for at least the next few posts, I will be writing about my adventures in Windows Phone 8 development.</p> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-64075699936114633112012-02-23T19:20:00.000-06:002012-02-23T19:21:36.621-06:00I’m a 5.8 out of 6 programmerIf you go to <a href="http://inter-sections.net/2007/11/13/how-to-recognise-a-good-programmer">How to recongnise a good programmer</a>, you will see one man’s idea of how to spot a good programmer. When looking around the web, <a href="http://groups.google.com/group/comp.databases.pick/browse_thread/thread/6826b34c57b330a5/61108d82f02bf021?lnk=raot">I stumbled upon this conversation about it</a>. The last post tried to adapt this to diesel mechanics. I’ve added my comments in <span style="color: red;">red</span><span style="color: white;"> to the post, since I think the poster does not have a clue what a programmer does. Maybe I can enlighten him a bit. (I’ve also colored his adaptation in </span><span style="color: #4bacc6;">blue</span><span style="color: white;">.</span><br />
<span style="color: #4bacc6;">Let's see how it applies to my business model. <br />I have a fleet of eighteen wheelers and I need to hire a bunch of mechanics to service Volvo, Kenworth and Mack trucks.</span> <br />
<span style="color: red;">Wow, to compare mechanics to programmers in the first place ... this guy hasn't a clue what a programmer does. But, just to play along lets see how this works out</span><br />
<span style="color: #4bacc6;">The article gives me two possible hiring scenarios which I've adapted to my business.</span> <br />
Positive indicators: <br />
Passionate about technology <br />
<span style="color: #4bacc6;">Heard about the latest F1 regenerative energy systems.</span><br />
<span style="color: red;">No, how about more like "Really likes to work on Trucks"?</span><br />
<br />
Programs as a hobby <br />
<span style="color: #4bacc6;">Tinkers with his own dirt bike.</span><br />
<span style="color: red;"><Sigh> I can see he just does not get it. More like: Loves to work on Trucks so will do it on his/her own time.</span> <br />
Will talk your ear off on a technical subject if encouraged <br />
<span style="color: #4bacc6;">NASCAR galore.</span><br />
<span style="color: red;">If you think NASCAR is a technical subject in you field then you will quickly be out of business.</span><br />
<br />
Significant (and often numerous) personal side-projects over the years <br />
<span style="color: #4bacc6;">Remember his Radio-Flyer cart !</span><span style="color: red;">Amazing how poorly you build your straw man! If I applied this to mechanics, I would say "Has always had grease under his fingernails." or maybe "Has rebuilt many different Trucks starting in High school"</span><br />
<br />
Learns new technologies on his/her own <br />
<span style="color: #4bacc6;">Reads "Popular Mechanics" magazine. </span><span style="color: red;">WTF! You really believe you can learn new technologies in "Popular Mechanics"? There is no way you can run a successful company ... Ok, I'll continue to play along. If I applied this to Truck mechanics, I would say "Keeps himself trained on the latest engine designs. Learns about all popular engine modifications."</span><br />
Opinionated about which technologies are better for various usages <br />
<span style="color: #4bacc6;">He's keen on Brembo brakes.</span><br />
<span style="color: red;">OK, I'll assume you know the difference between technologies and products, right? This is where some of your analogy starts to break down. When was there a major new development in internal combustion engine design? Basic diesel technology is how old?</span><br />
Very uncomfortable about the idea of working with a technology he doesn't believe to be “right” <br />
<span style="color: #4bacc6;">Hates the old carburetor thing.</span><br />
<span style="color: red;">So you think that a great diesel mechanic would love to get a job with you working on your "Water and Chicken poop powered" Trucks?</span><br />
<br />
Clearly smart, can have great conversations on a variety of topics <br />
<span style="color: #4bacc6;">iTune, iPhone, Roberta Black, Iraq etc.</span><br />
<span style="color: red;">Another place that this analogy breaks down. <Sigh> I'll just keep quiet on this one.</span><br />
<br />
Started programming long before university/work <br />
<span style="color: #4bacc6;">As a teenager repaired the toaster and changed the kitchen faucet.</span><span style="color: red;">More like, knew what a torque wrench was before he started his first mechanics class.</span> <br />
Has some hidden “icebergs”, large personal projects under the CV radar <br />
<span style="color: #4bacc6;">Wants to tinker with a jet ski watercraft. </span><span style="color: red;">Close, more like, knows how to alter a jet ski engine to get a 50% power boost without damaging the engine.</span><br />
<br />
Knowledge of a large variety of unrelated technologies (may not be on CV) <br />
<span style="color: #4bacc6;">Knows the difference between a CD, a regular DVD and a blue-ray DVD.</span><span style="color: red;">If you are not being deliberately stupid, then <sigh> I’ll just keep quiet.</span><br />
Negative indicators: <br />
Programming is a day job <br />
<span style="color: #4bacc6;">Does truck service & repairs for a living.</span><br />
<span style="color: red;">More like "Never turns a wrench unless he is paid to, and even then he bitched about it. Why does he do it - its a paycheck."</span><br />
<br />
Don’t really want to “talk shop”, even when encouraged to <br />
<span style="color: #4bacc6;">Prefers to check the service manuals and do the job at hand.</span><br />
<span style="color: red;">Here you have is completely backward. This is a prime example of "Learns new technologies on his/her own" above. Instead, the correct example would be, "Never wants to learn the tips and tricks of other experts, but would rather scratch his ass and complain about the pay"</span><br />
<br />
Learns new technologies in company-sponsored courses <br />
<span style="color: #4bacc6;">If I am going to send him to a GM training course he will gladly obliged.</span><br />
<span style="color: red;">Nope, more like "Hey Bob, we are going to expand and start working on FIAT's. The Community College is offering night courses." and Bob replies, "Screw you boss, if you want me to go, it's during work hours, your paying and I'm not going to make up the time."</span><br />
<br />
Happy to work with whatever technology you’ve picked, “all technologies are good” <br />
<span style="color: #4bacc6;">If we decide to buy GM trucks he will gladly work on them</span><br />
<span style="color: red;">GM trucks? No more like now your going to work on HVAC systems and by-god they had better be as good at is as they were at diesels.</span> <br />
Doesn’t seem too smart <br />
<span style="color: #4bacc6;">He does not seem interested in iTune, iPhone, Roberta Black, Iraq etc.</span><br />
<span style="color: red;">Another place that this analogy breaks down. <Sigh> I'll just keep quiet on this one.</span><br />
<br />
Started programming at university <br />
<span style="color: #4bacc6;">Learned how trucks are built, how to service them and had hands on practical experience under the supervision of master mechanics in an accredited school with his major in Volvo engine and control module diagnostic and repair and minor in Kenworth engine and transmission repair and has a "specialist" certification.</span><br />
<span style="color: red;">Another place that this analogy breaks down, but I'll give it a try. First time the future mechanic ever heard of a ratchet wrench when he got the list of required tools for his new degree. If we were to equate a CS degree to a tech degree and certification, it the tech degree and certification would guarantee that the student has shown that he knows exactly what each tool is, how it is used and if necessary, how to make one from scratch.</span> <br />
All programming experience is on the CV <br />
<span style="color: #4bacc6;">Left out his alma-mater racing club where he is the chief mechanic.</span><br />
<span style="color: red;"><sigh></span><br />
<br />
Focused mainly on one or two technology stacks (e.g. everything to do with developing a java application), with no experience outside of it <br />
<span style="color: #4bacc6;">He is focused on Volvo and Kenworth and has really no experience with Tatra, Zim, Hino, FIAT and other trucks.</span><br />
<span style="color: red;">Almost right, if the other types of trucks used different types of engines built with different materials and you needed a completely different set of tools that the mechanic would have no idea how to use.</span><br />
<span style="color: #4bacc6;">I don't know why, but I would hire the guy/gal with the negative indicators. Lucian</span> <br />
Well, Lucian, what your saying is that you would rather have a person that only learned what a wrench is after he started school, only does the work because he is getting a paycheck, doesn't even like talking about what he does, refuses to learn anything unless he is paid to do it and thinks that he is equally skilled at working on HVAC as he is on a diesel engine because "All technologies are good"?<br />
Wow, I give your company 6 to 8 weeks before either the "mechanics" you hire starts your building on fire, or you are sued out of business because a "mechanic" put Mack parts on a Kenworth. (remember, all technology is good, right?)<br />
This is why comparing a mechanic (a job where there is always only one way that things go together) and a programmer (a job where there are literally a million ways to do things. Most of them the wrong way, but quite a few almost correct if not equally correct.)<br />
When every Trucking company builds there own engines, changes the type of engine every couple of years, fixing the engine can be done 1000 different ways, and require the mechanics to use a whole different set of tools for each new type, then we can START to compare diesel truck mechanics to programmers.Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-433124037110879712011-10-14T10:44:00.004-05:002011-10-14T10:51:02.804-05:00Merging multiple DataTables from different databases in parallel<p>In a previous post (<a href="http://oldschooldotnet.blogspot.com/2008/10/linq-to-rescue.html">LINQ to the rescue!</a>) I used linq to merge multiple DataTables, sort them and exclude duplicates.</p><p>But, what about filling those DataTables in the first place. If, like I, you have multiple databases in production at work and need to show to the users a “database agnostic” view of their data, you need to query all those databases and merge the data. </p><p>Querying a large number of databases in serial is a slow process, but playing with threads seems … dangerous.</p><p>Well, with the new Parallel libraries, this becomes very simple to do, even with Oracle ( ;-) )</p><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><div style="background: #ddd; max-height: 300px; overflow: auto"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"><li><span style="color:#0000ff">var</span> dbs = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span><<span style="color:#0000ff">string</span>>() { <span style="color:#a31515">"Database1"</span>, <span style="color:#a31515">"Database2"</span>, <span style="color:#a31515">"Database3"</span>, <span style="color:#a31515">"Database4"</span> };</li>
<li style="background: #f3f3f3"><span style="color:#0000ff">var</span> dts = <span style="color:#0000ff">new</span> <span style="color:#2b91af">DataTable</span>[dbs.Count];</li>
<li> </li>
<li style="background: #f3f3f3"><span style="color:#2b91af">Parallel</span>.For(0, dbs.Count, i => LoadData(dbs[i], dts, i));</li>
<li> </li>
<li style="background: #f3f3f3"><span style="color:#0000ff">var</span> myTable = dts[0];</li>
<li> </li>
<li style="background: #f3f3f3"><span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> i = 1; i < dbs.Count; i++) myTable.Merge(dts[i]);</li>
<li> </li>
<li style="background: #f3f3f3"><span style="color:#0000ff">var</span> dtLinqData = (<span style="color:#0000ff">from</span> MyRow <span style="color:#0000ff">in</span> myTable.AsEnumerable()</li>
<li> <span style="color:#0000ff">orderby</span> MyRow.Field<<span style="color:#0000ff">string</span>>(<span style="color:#a31515">"Name"</span>) <span style="color:#0000ff">ascending</span></li>
<li style="background: #f3f3f3"> <span style="color:#0000ff">select</span> MyRow).Distinct().CopyToDataTable();</li>
<li> </li>
<li style="background: #f3f3f3"> </li>
<li><span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> LoadData(<span style="color:#0000ff">string</span> db, <span style="color:#2b91af">DataTable</span>[] dts, <span style="color:#0000ff">int</span> index)</li>
<li style="background: #f3f3f3">{</li>
<li> <span style="color:#2b91af">DataTable</span> returnValue = <span style="color:#0000ff">null</span>;</li>
<li style="background: #f3f3f3"> </li>
<li> <span style="color:#0000ff">using</span> (<span style="color:#0000ff">var</span> connection = <span style="color:#0000ff">new</span> <span style="color:#2b91af">OracleConnection</span>(GenerateConnectionString(db, <span style="color:#a31515">"MyUserId"</span>, <span style="color:#a31515">"MyPassword"</span>)))</li>
<li style="background: #f3f3f3"> {</li>
<li> <span style="color:#0000ff">using</span> (<span style="color:#0000ff">var</span> dataAdapter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">OracleDataAdapter</span>(<span style="color:#a31515">"SELECT * FROM CUSTOMER"</span>, connection))</li>
<li style="background: #f3f3f3"> {</li>
<li> returnValue = <span style="color:#0000ff">new</span> <span style="color:#2b91af">DataTable</span>();</li>
<li style="background: #f3f3f3"> dataAdapter.Fill(returnValue);</li>
<li> }</li>
<li style="background: #f3f3f3"> }</li>
<li> </li>
<li style="background: #f3f3f3"> dts[index] = returnValue;</li>
<li>}</li>
<li style="background: #f3f3f3"> </li>
<li><span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> GenerateConnectionString(<span style="color:#0000ff">string</span> instance, <span style="color:#0000ff">string</span> userId, <span style="color:#0000ff">string</span> password)</li>
<li style="background: #f3f3f3">{</li>
<li> <span style="color:#0000ff">return</span> <span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"data source = {0}; user id = {1}; password={2}; pooling=true; Connection Lifetime=60; Max Pool Size=50"</span>, instance, userId, password);</li>
<li style="background: #f3f3f3">}</li>
</ol></div></div>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-32453905234947361352011-07-07T13:27:00.000-05:002011-07-07T13:27:54.629-05:00Viewing the contents of a binary file in Visual Studio<p>The toolset included in Visual Studio is just massive. I swear that I could use Visual Studio for a lifetime and I still would not have plumbed all its depths.</p> <p>With that thought in mind, I just realized that I need not look for poor third party applications to look inside a binary file. I can use my trusty IDE Swiss Army knife, Visual Studio.</p> <p>There are two ways to view and edit a binary file in Visual Studio:</p> <ol> <li>Simply open a file with the extension of .BIN <li>After selecting the file in “Open –> FIle…” but before you click the “Open” button, instead click on the dropdown arrow on the “Open” button and select “Open With …”. Then select “Binary Editor” from the list.</li></ol> <p>Either way you are then presented with the standard type of Binary File editor (3 columns, 1- The Offset, 2- The binary data & 3- The ASCII representation of the binary data).</p> <p>In this editor, you can copy, paste, add, alter and delete bytes!</p> <p>If only I had known this years ago!</p> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-54809505780232499652011-05-01T22:02:00.001-05:002011-05-01T22:02:08.397-05:00Oracle Greater Than/Less Than calculations in the select list<p>At work I recently had a simple need.  I had a table with data.  One of the columns is a date-time stamp – lets call it “Last_Login_Date”.  I wanted a “Boolean” column that was a false if the value was less than 60 days old and true if it was older than 60 days. (Yes, I know that Oracle does not have a Boolean data type so how about Zero (0) for false and One (1) for true, OK?)</p> <p>Ok, you would think that this would be simple: Just add the calculation in the select list, right? SYSDATE - Last_Login_Date > 60 AS Is_Old_Account.</p> <p>But no, nothing can be easy can it.</p> <p>With a fairly cryptic combination of Oracle commands I replicated what I wanted.  Here it is:</p> <p>DECODE(GREATEST(FLOOR(SYSDATE – NVL(LAST_LOGIN_DATE, TO_DATE('2000/01/01', 'yyyy/mm/dd')), 60), 60, 0, 1) AS IS_OLD_ACCOUNT</p> <p>And, here is the breakdown:</p> <p>First NVL incase the field had never been populated.</p> <p>Next, FLOOR to turn the difference into an integer (probably not needed, but during debugging, having an integer was easier to deal with.</p> <p>Then, GREATEST takes two values, the date difference and my max value.  So, if the date difference is less than 60, the  GREATEST function will return 60.</p> <p>Lastly DECODE will look at the value and say – If it is 60 return 0, else return 1.  </p> <p>So, the end result is if the value is 60 or less, the value is 0 else it is 1.</p> <p><font color="#ff0000">Note:  I could have ran the SQL twice with a JOIN command and add to the where clauses the filters of  SYSDATE - Last_Login_Date > 60 and SYSDATE - Last_Login_Date <= 60 and a dummy column in the select list added in out “Boolean” column IS_OLD ACCOUNT, but this did not seem very efficient.</font></p> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-27759095600052628392011-04-16T14:43:00.000-05:002011-04-16T14:43:00.271-05:00Calculating the average of two angles (two bearings actually)<p>I recently needed to find the average of two angles.  I was programmatically creating a irregular polygon. I wanted to draw a small square at the points of the polygon, and I wanted the squares to be rotated to the average of the two lines that met at that point.</p> <p>The issue is that if you have two bearings, one at 20° and one at 350°, or one at 15° and one at 315°. If you just average the two numbers, you get 185°, but the more appropriate number is 5°.  This is called by some a “Wraparound issue” and if you search the web you will see lots of ways to solve this problem. Unfortunately they mostly try to solve it using a mathematical equation.  Now for people that have read this blog for awhile know that I am not allergic to math, but if we can solve this problem simply with an algorithm, we should … that’s what computers are for, right?</p> <p>So, here is my algorithm and the thought behind it.</p> <hr /> <p>(Assumptions: 0 >= bearings < 360)</p> <p>First if you look at the difference between the two bearings, you will see that there are two possibilities, the actual difference is greater than 180° or less than 180°.  Since we are only concerned about “fixing” the issue when the difference is greater than 180°, that is the first thing we will check.</p> <p>We will call the smaller value bearing <strong>bearingA</strong> and the larger value bearing <strong>bearingB</strong>.</p> <p>Since we know that bearingB has a larger value and that the difference is greater than 180, so bearingB > 180.</p> <p>So, if we subtract 360  –  bearingB, then just add bearingA + bearingB and divide the total in half, we are 90% there.</p> <p>One last check. If the result is less than 0, we need to add 360 back in.</p> <table border="1" cellspacing="0" cellpadding="12" width="434"><tbody> <tr> <td valign="top" width="189"><u>So, example #1</u> <pre>20° & 350°<br />350 – 20 > 180<br />350 – 360 = –10<br />(–10 + 20) / 2 = 5<br />5 ≥ 0<br />= 5 °</pre><br /> </td><br /><br /> <td valign="top" width="243"><u>So, example #2</u> <br /><br /> <pre>15° & 315°<br />315 – 15 > 180<br />315 – 360 = –45<br />(-45 + 15) / 2 = –30<br />–30 < 0–30 + 360 = 354°</pre><br /> </td><br /> </tr><br /> </tbody></table><br /><br /><p>And here is the code:</p><br /><br /><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><div style="background: #ddd; max-height: 300px; overflow: auto"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"><li><span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">double</span> GetAverageBearing(<span style="color:#0000ff">double</span> bearingA, <span style="color:#0000ff">double</span> bearingB)</li><li style="background: #f3f3f3"> {</li><li> <span style="color:#0000ff">if</span> (bearingA > bearingB)</li><li style="background: #f3f3f3"> {</li><br /><li> <span style="color:#0000ff">var</span> temp = bearingA;</li><li style="background: #f3f3f3"> bearingA = bearingB;</li><br /><li> bearingB = temp;</li><li style="background: #f3f3f3"> }</li><li> </li><li style="background: #f3f3f3"> <span style="color:#0000ff">if</span> (bearingB - bearingA > 180) bearingB -= 360;</li><li> </li><li style="background: #f3f3f3"> <span style="color:#0000ff">var</span> finalBearing = (bearingB + bearingA)/2;</li><li> </li><li style="background: #f3f3f3"> <span style="color:#0000ff">if</span> (finalBearing < 0) finalBearing += 360;</li><li> </li><li style="background: #f3f3f3"> <span style="color:#0000ff">return</span> finalBearing;</li><li> }</li></ol></div></div> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com1tag:blogger.com,1999:blog-6672560504141734407.post-30622539204779843122011-04-09T16:42:00.000-05:002011-04-09T16:43:29.934-05:00Scripting C++/cli with IronPython (Visual Studio 2008 & IronPython 2.6.1)<p>Even though there has been a lot of talk about IronPython, there has been very little info about how to use it with C++/cli.  I’ve actually found posts claiming that it is not possible to use IronPython with C++/cli.</p> <p>Well, it is possible and easy, once you have a working example.  If, not then … well, lets just hope your hair will grow back.</p> <p>Ok, I’m never one to take the easy way out, but I started by creating a C# dll that called my IronPython script and then called the C# dll from C++/cli.  That worked but seemed overly complicated.  If you do not mind a middleman then I guess it is ok, but if you want to go straight from C++/cli to IronPython, read on.</p> <p>When I first tried to write a call to an IronPython script from  C++/cli, I tried a direct conversion of C# code into C++/cli code.  That didn’t work, so I then tried using RedGate’s .Net Reflector and the <a href="http://www.sandpapersoftware.com/Main/Reflector.html">C++/cli add-in for .Net Reflector</a>.  This got me 70% there.  Combining both with some trial and error got me the rest of the way.  </p> <p>Funny, but when you look at the code, it seems so simple – yet getting there was not easy.</p> <p>So, the following snippet shows a simple usage of IronPython as a scripting language.  It takes the first parameter passed in prints it to the console, passes it to the IronPython script: ipyStrings.ipy, then prints to the console the value of the same parameter that was passed back.  The IronPython code takes the string, prints it, reverses it, then sends it back.</p> <p>C++/cli code:</p> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">int</span> main(<span style="color: #0000ff">array</span><System::String ^> ^args) </li> <li style="background: #f3f3f3">{ </li> <li>    <span style="color: #0000ff">try</span> </li> <li style="background: #f3f3f3">    { </li> <li>        <span style="color: #0000ff">if</span>(args->Length>0) </li> <li style="background: #f3f3f3">        {    </li> <li>            String^ filename = <span style="color: #a31515">"ipyStrings"</span>; </li> <li style="background: #f3f3f3">            String^ path = Assembly::GetExecutingAssembly()->Location; </li> <li>  </li> <li style="background: #f3f3f3">            ScriptEngine^ engine = Python::CreateEngine(); </li> <li>            ScriptScope^ scope = engine->CreateScope(); </li> <li style="background: #f3f3f3">            ScriptSource^ source = engine->CreateScriptSourceFromFile </li> <li style="background: #f3f3f3">            (String::Concat(Path::GetDirectoryName(path), <span style="color: #a31515">"\\"</span>, filename, <span style="color: #a31515">".ipy"</span>)); </li> <li>        </li> <li style="background: #f3f3f3">            Console::WriteLine(args[0]); </li> <li>  </li> <li style="background: #f3f3f3">            scope->SetVariable(<span style="color: #a31515">"passedArgs"</span>, args[0]);            </li> <li>            source->Execute(scope); </li> <li style="background: #f3f3f3">  </li> <li>            Console::WriteLine(scope->GetVariable<String ^>(<span style="color: #a31515">"passedArgs"</span>)); </li> <li style="background: #f3f3f3">        }                                    </li> <li>    } </li> <li style="background: #f3f3f3">    <span style="color: #0000ff">catch</span>(Exception ^e) </li> <li>    { </li> <li style="background: #f3f3f3">        Console::WriteLine(e->ToString()); </li> <li>    } </li> <li style="background: #f3f3f3">  </li> <li>    Console::ReadLine(); </li> <li style="background: #f3f3f3">  </li> <li>    <span style="color: #0000ff">return</span> 0; </li> <li style="background: #f3f3f3">} </li> </ol> </div> </div> <p>Python code:</p> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li>import clr </li> <li style="background: #f3f3f3">  </li> <li>print <span style="color: #a31515">"Passed in: "</span> + passedArgs </li> <li style="background: #f3f3f3">passedArgs = passedArgs[::-1] </li> <li>  </li> <li style="background: #f3f3f3">print <span style="color: #a31515">"Sending back: "</span> + passedArgs </li> </ol> </div> </div> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com3tag:blogger.com,1999:blog-6672560504141734407.post-68110171086295819012011-04-07T12:37:00.001-05:002011-04-07T12:56:48.015-05:00Random Numbers on a Bell Curve in C#<p>Have you ever wanted to generate some random numbers but with a distribution pattern other than the normal even pattern?</p> <p>Well in a recent project I did. I wanted a weighted distribution pattern that looked like a bell curve. </p> <p>I looked around yes there were some answers, but most got a lot deeper into math than I wanted or needed. I simply wanted to generate a number with the probability that it was in the center of the range be greater than the probability that it was on the edges – in other words, it fit on a Bell Curve.</p> <p>I cannot credit what post where gave me the simple solution, or I would post a link. Here is a simple Extension Method to the Random class. </p> <p>It takes two parameters: </p> <ol> <li>Steps: How many numbers in each “Chunk” do you want. If you want a number between 0 & 600 and set the Steps equal to 50, then the midpoint value (300) will be much more likely than 0 or 300. <li>MaxValue: The possible range for the random number will be 0 to MaxValue - 1.</li></ol> <p>Now keep in mind that this is not mathematically perfect. If you do not choose a step value that is a divisor of your MaxValue then you will not get the full range. But, having said that, this is a great “Quick & Dirty” way to get a good approximation of a random bell curve.</p> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RandomExtender</span> <li style="background: #f3f3f3">{ <li> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span> NormalNext(<span style="color: #0000ff">this</span> <span style="color: #2b91af">Random</span> rnd, <span style="color: #0000ff">int</span> Steps, <span style="color: #0000ff">int</span> MaxValue) <li style="background: #f3f3f3"> { <li> <span style="color: #0000ff">int</span> count = 0; <li style="background: #f3f3f3"> <span style="color: #0000ff">int</span> val = 0; <li> <li style="background: #f3f3f3"> <span style="color: #0000ff">if</span> (Steps < 1) <span style="color: #0000ff">return</span> 0; <li> <li style="background: #f3f3f3"> <span style="color: #0000ff">while</span> (++count * Steps <= MaxValue) val += rnd.Next(Steps); <li> <li style="background: #f3f3f3"> <span style="color: #0000ff">return</span> val; <li> } <li style="background: #f3f3f3">} </li></ol></div></div> <p>Here is a picture of 20,000 random numbers with Steps = 50 & MaxValue = 600.</p> <p><a href="http://lh3.ggpht.com/_t6xxfboJxk0/TZ32WvePuAI/AAAAAAAAAEY/XjNnnSeUQa0/s1600-h/BellCurve%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BellCurve" border="0" alt="BellCurve" src="http://lh5.ggpht.com/_t6xxfboJxk0/TZ32XKkTs-I/AAAAAAAAAEc/aoPF2MH_seM/BellCurve_thumb%5B1%5D.png?imgmax=800" width="339" height="182"></a></p> Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-61334614677955511932010-07-12T09:59:00.004-05:002010-07-14T12:35:24.558-05:00c++ dll error when using MD[d]It is possible for any programmer, even one that has been in the "trade" for a loooong time, to be an absolute idiot - especially when they are learning something new. Not always does hard learned skills help when trying something new.<br /><br />Take my latest gaff as an example. Now I've been coding C++/cli mixed mode dlls since 2005, but I'd taken some time off right before Windows 7 arrived. Well, it was time to get back into the saddle, so I started work on a long dormant project and got it to a Beta state.<br /><br />I rolled out the debug dll to my testers and when they tested it on Windows 7, Boom!.<br /><br />Ok, time for some research .... lots of time for research.<br /><br />Well, I finally found - that in a non-/cli C++ dll, I could use the /MT compiler switch and it would work just fine on XP and Win7. But if I used the /MD compiler switch, which is required to use C++/cli, it would still run on a clean XP install, but not on a clean Win7 install.<br /><br />Arrrgggg!<br /><br />After many posts on many different forums, I decided to try making a install package (which I've NEVER had to do before - its just a dll after all!) but Visual Studio pulled in two additional files, that it said were needed to run.<br /><br />Well - Success!! Sort of. But, I happily posted my results on the various forums. One reply (Thanks Peter) pointed out that they were Debug files and that it may be a licence issue if I were to disseminate them. <br /><br />That got me to wondering if this was all a Debug/Release mode issue.<br /> <br />Well, it was. I started with a new copy of my Win7 Virtual PC that also installs the C++ runtime files.<br /> <br />I then pushed a debug version to it just to verify that we still had the issue. Yep.<br /> <br />Then I pushed a release version to it and viola! It works. Dumb, dumb, dumb! <Hitting head on wall><br /> <br />Why do I make things so hard for myself?Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-14636492937956541502010-07-07T11:19:00.004-05:002010-07-07T11:56:24.430-05:00C++/cli -> calling c# dll -> calling OpenFileDialog issueI write extensions to a Cartography program called Campaign Cartographer 3 (CC3 for short). It is sold by one of the most involved companies I have ever had the pleasure to be associated with <a href="http://www.profantasy.com">ProFantasy</a>.<br /><br />To program an extension to CC3, you need to be able to write old school windows dlls. You remember the ones! They have a DllMain function? I saw that shudder, you do remember.<br /><br />Well, whenever I can I use C++/cli (the .net version of C++) and if the extension is very complicated, I do most of my coding in C# and reference the C# dll from C++/cli. You can mix and match plain old C++ and C++/cli (and C#) through IJW (Believe it or not, that stands for "It Just Works"). As a matter of fact all my newer extensions hook into C++/cli, even if I do not use it - I want it there just in case.<br /><br />Well, in my latest project, a self-contained wiki-like document reader/writer (hard to explain - maybe in a later post), I needed to call the standard .net openFileDialog and saveDileDialog controls.<br /><br />All of a sudden, I'm getting COM errors!?!? <br /><br /><strong>'System.Threading.ThreadStateException' occurred in System.Windows.Forms.dll<br /><br />Additional information: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.</strong><br /><br /><em>OLE calls? How old an error is that!?</em><br /><br />Well, it seems that if you try to call the .net file dialogs from C++/cli you need to do it from a STA Thread. But, since I cannot access the main thread, remember this is someone elses application - all I have access to is my DllMain. Well, after searching around and asking about how to deal with this error on StackOverflow.com - I got my answer, sort of.<br /><br />The helpful people over at StackOverflow pointed out that I needed to start my own thead as an STAThread. They also gave me advice on how to do this via COM.<br /><br />Well, I'm not adverse to admit that the amount of COM knowledge I have could be held in a teacup. But the Thread advice solved the problem. I just did it the C++/cli way!<br /><br />First you need to isolate the code you want to run into a class.<br /><br /><code>ref class StaClass<br />{<br /> void CallWiki() <br /> {<br /> WikiNotes::FrmWiki fw; <br /> fw.ShowDialog();<br /> }<br />}</code><br /><br />Then from my main C++/cli code, I just create a new thread and call "CallWiki"<br /><br /><code>StaClass wiki = gcnew StaClass;<br /><br />ThreadStart^ threadDelegate = gcnew ThreadStart(wiki, &StaClass::CallWiki); <br />Thread^ newThread = gcnew Thread(threadDelegate, 0); <br />newThread->SetApartmentState(ApartmentState::STA); <br />newThread->Start();</code> <br /><br />Remember though, if you want to wait until your new thread finishes, like I did, then you can:<br /><br /><code>while (!workerThread->IsAlive);<br />regularThread->Join();<br /></code>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-73260909342679380512010-06-26T19:46:00.000-05:002010-06-26T19:46:00.253-05:00Fixing "Random" Default Button Behavior (asp.net)Way back when I first started developing web applications, I quickly determined that you had to have the default button as the first submit button in the HTML markup.<br /><br />A recent trouble ticket at work detailed that the default button was behaving erratically. It seemed that it was working only every other time. Yet, the location of the button never changed, so how could that be?<br /><br />Here is a link of an example where I have recreated the issue.<br /><br /><a href="http://www.leesaunders.net/examples/defaultbutton/broken.aspx">Broken Default Button</a><br /><br />To recreate the broken behavior, set the focus in one of the textboxes or a radiobuton and then press the enter key. The panel should minimize and a second panel should now become visible. click on the button in the upper right corner to re-expand the original panel and repeat the test.<br /><br />every time both panels are visible, the default button switches to the button in the lower panel.<br /><br />The fix is quite simple. Using asp.net 2.0 or higher simply add this one line to the Page_Load function: Page.Form.DefaultButton = "Button ID";<br /><br /><a href="http://www.leesaunders.net/examples/defaultbutton/fixed.aspx">Fixed Default Button</a>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-12532720645759330022010-06-22T00:45:00.000-05:002010-06-22T00:45:00.106-05:00Dynamic type simplifies returning an anonymous type from a functionEver since Microsoft added anonymous types to C#, I've tried to use them in the manner that Microsoft themselves described: "Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to first explicitly define a type."<br /><br />And, it seemed to me that one of the best uses for one of these "temporary" objects is as a return type from a function. Yet, Microsoft expressly designed anonymous types to not be usable as a return type. Sure, you could have the return type as Object, but then you could not cast it back as the type because it is "anonymous".<br /><br />Here is a <a href="http://tomasp.net/blog/cannot-return-anonymous-type-from-method.aspx">Blog Post</a> the explains how to return an anonymous type using a casting function.<br /><br />Now though it is much simpler. All you need to do is set the return value to "dynamic". Since the dynamic type is determined at run time instead of compile time, compiler type checking is bypassed. At run time, when dynamic variables are referenced, they then have their methods and properties verified. So you can, in code, reference a property without having the compiler knowing if the type actually has the property.<br /><br />One caveat: This will only work within the same assembly. From a design standpoint, this makes sense. Why pass along an anonymous type between assemblies? It just does not make any sense. Inside a single assembly it is local and you are in full control, but between assemblies? You never know who is going to use it. You cannot assume that they would have any idea what is being returned.<br /><br /><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><br /><div style="background: #ddd; overflow: auto"><br /><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"><br /><li><span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Main(<span style="color:#0000ff">string</span>[] args)</li><br /><li style="background: #f3f3f3">{</li><br /><li> <span style="color:#0000ff">var</span> d = ReturnAnonamoustype();</li><br /><li style="background: #f3f3f3"> </li><br /><li> <span style="color:#2b91af">Console</span>.WriteLine(d.Name);</li><br /><li style="background: #f3f3f3"> <span style="color:#2b91af">Console</span>.Read();</li><br /><li>}</li><br /><li style="background: #f3f3f3"> </li><br /><li><span style="color:#0000ff">static</span> <span style="color:#0000ff">dynamic</span> ReturnAnonamoustype()</li><br /><li style="background: #f3f3f3">{</li><br /><li> <span style="color:#0000ff">return</span> <span style="color:#0000ff">new</span> { Name = <span style="color:#a31515">"Bob"</span>, Age = 50 };</li><br /><li style="background: #f3f3f3">}</li><br /></ol><br /></div><br /></div>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-10931831134509386672010-06-18T12:00:00.000-05:002010-06-18T12:00:01.244-05:00Returning a string array to Javascript from SliverlightThis took a lot of trial and error, but I finally figured out how to return to Javascript a string array. There where many different examples out on the web to call Javascript, passing a string array. But, no examples had Javascript calling a Silverlight function with a string array as the return value.<br /><br />I first tried the direct approach:<br /><br />javascript:<br /><code><pre>function TalkToSilverlight(data) {<br /> var control = document.getElementById("silverlightControl"); <br /> var myStringArray = control.Content.Page.ReturningStringArray();<br /> alert('length = ' + myStringArray.length + " : Value of First Element = " + myStringArray[0]);<br />}</pre></code><br /><br />Silverlight C#<br /><code><pre>public App()<br />{<br /> HtmlPage.RegisterScriptableObject("Page", this);<br /> //The rest I've elided<br />}<br /><br />[ScriptableMember]<br />public string[] ReturningStringArray() <br />{<br /> return new [] { "e", "i", "e", "i", "o" };<br />}</pre></code><br /><br />Well to make a long story short, a small little mention of the IList interface on MSDN was the key, all I "needed" to do (as opposed to all the changes I tried) was change the return value from string[] to IList<string>.Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-61962206656194076432010-06-12T19:41:00.003-05:002010-06-12T19:55:59.585-05:00Serendipity strikes againCan you believe it? After working my free asp.net template example and learning how to take a free web template and integrating it into asp.net, I acquired quite a few skills.<br /><br />And now the company that I work for has started to work on a new web offering and for the first time decided to use an outside company to do the web UI design. They delivered HTML, CSS and images. So, now I am doing professionally exactly what I did previously for fun.<br /><br />It is almost as if I was practicing for my current task. If that is not Serendipity, then I do not know what is.Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-30003296658469330072010-05-20T10:52:00.003-05:002010-05-20T10:56:33.548-05:00Closing Down 1and1, Finally!Warning! I am finally moving my last domain, leesaunders.net, to GoDaddy. I've waited this long because this domain hosts all my examples and I wanted to spare everyone from the pain as long as possible.<br /><br />Well, last night the domain was transfered to GoDaddy and will be down until GoDaddy can bring it back up in my new hosting package.<br /><br />Sorry for the blackout - but, it is all for the best.Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-88637606118003343422010-05-12T19:35:00.003-05:002010-05-12T20:05:20.486-05:00Is UI or AI more important in board game programming?Board games with a great UI with such a poor AI that you can always win with half your brain tied behind your back. Or, Board games with a great AI with such a poor UI that it is almost physically painful to play.<br /><br />We've all seen both. <br /><br />We've all played both.<br /><br />But what about the great/mediocre combinations? Where should developers spend their time? Perfecting the AI or the UI?<br /><br />Obviously, (from all the professionally produced board game programs I purchased over the years) the UI sells units. <br /><br />But, it is the AI keeps you playing. And its the AI that convinces me to buy when the program can be downloaded for a demo. I just recently experienced that with <br /><a href="http://railgamefans.com/ebp/index.htm">Empire Builder Pronto</a>. The UI is mediocre ... to be kind. <br /><br />But the UI! Wow, I have not been able to beat the AI yet and that is why I plunked down the cash to buy the game.<br /><br />So, all you board game programmers out their: make sure the UI is playable, but make your AI as tough as you possibly can!Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-11720564646775790452010-02-04T22:35:00.004-06:002010-02-04T22:35:02.225-06:00ASP.Net - Multiple Bin Folders support a plug-in websiteIt was way back in 2001 when I was tasked at my company to implement our internal web application in ASP.Net. This site not only reported on most of the company's critical functions but also contained very complex data management screens. The sheer size of the site precluded it from being in a single dot net solution.<br /><br />So, after many hours of searching the Internet in vain for a solution, I finally started to experiment on my own. I discovered that any project could be added to the site by copying the compiled DLLs into the sites bin directory. This works, but it is not the most elegant solution.<br /><br />Well, many years to late, at least for the company site, I've discovered a much more elegant solution. (And when I say I've discovered it, I mean that I've finally found the information on the internet :-))<br /><br />Here is the link to the original information:<br /><a href="http://www.hanselman.com/blog/PermaLink.aspx?guid=4d0ef4fb-f8ae-4355-a658-3c0432c98dbe">http://www.hanselman.com/</a><br /><br />This post refers to ASP.Net 1.1, but I've taken the time to verify that this still does work in ASP.Net 3.5.Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com0tag:blogger.com,1999:blog-6672560504141734407.post-54664307967154758932010-01-30T16:24:00.004-06:002010-01-30T16:24:00.248-06:00StrSpn & StrCSpn in C#After converting the c/c++ string tokenizing command strtok to c#, I thought I would look around to see there were any other interesting string commands in c/c++ that had not been integrated into c#. What I found was strspn and strcspn.<br /><br />strspn (String Span) Returns the length of the longest substring that begins at the start of the string and consists only of the characters found in the supplied character array.<br /><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><br /><div style="background: #ddd; max-height: 300px; overflow: auto"><br /><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"><br /><li><span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> strspn(<span style="color:#0000ff">string</span> InputString, <span style="color:#0000ff">char</span>[] Mask)</li><br /><li style="background: #f3f3f3">{</li><br /><li> <span style="color:#0000ff">int</span> count = 0;</li><br /><li style="background: #f3f3f3"> </li><br /><li> <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> c <span style="color:#0000ff">in</span> InputString)</li><br /><li style="background: #f3f3f3"> {</li><br /><li> <span style="color:#0000ff">if</span> (!Mask.Contains(c)) <span style="color:#0000ff">break</span>;</li><br /><li style="background: #f3f3f3"> </li><br /><li> count++;</li><br /><li style="background: #f3f3f3"> }</li><br /><li> <span style="color:#0000ff">return</span> count;</li><br /><li style="background: #f3f3f3">}</li><br /></ol><br /></div><br /></div><br /><br />strcspn (String Complement Span) Returns the length of the longest substring that begins at the start of the string and contains none of the characters found in the supplied character array.<br /><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><br /><div style="background: #ddd; max-height: 300px; overflow: auto"><br /><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"><br /><li> <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> strcspn(<span style="color:#0000ff">string</span> InputString, <span style="color:#0000ff">char</span>[] Mask)</li><br /><li style="background: #f3f3f3"> {</li><br /><li> <span style="color:#0000ff">int</span> count = 0;</li><br /><li style="background: #f3f3f3"> </li><br /><li> <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> c <span style="color:#0000ff">in</span> InputString)</li><br /><li style="background: #f3f3f3"> {</li><br /><li> <span style="color:#0000ff">if</span> (Mask.Contains(c)) <span style="color:#0000ff">break</span>;</li><br /><li style="background: #f3f3f3"> </li><br /><li> count++;</li><br /><li style="background: #f3f3f3"> }</li><br /><li> <span style="color:#0000ff">return</span> count;</li><br /><li style="background: #f3f3f3"> }</li><br /><li>}</li><br /></ol><br /></div><br /></div>Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com2tag:blogger.com,1999:blog-6672560504141734407.post-48364191410058987692010-01-25T20:31:00.004-06:002010-01-25T20:31:00.177-06:00C# TechTip #1 Using MaxLength as AutoTabSo, for all those old VB6 programmers out there: Remember The Visual Basic Programmers Journal TechTip publications.<br /><br />For me, those pamphlets where the most eagerly waited part of my VBPJ publication. Here are the links to PDF versions.<br /><br /><A href="http://vb.mvps.org/articles/techtips/techtip1.pdf">VBPJ TechTips #1</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip2.pdf">VBPJ TechTips #2</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip3.pdf">VBPJ TechTips #3</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip4.pdf">VBPJ TechTips #4</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip5.pdf">VBPJ TechTips #5</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip6.pdf">VBPJ TechTips #6</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip7.pdf">VBPJ TechTips #7</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip8.pdf">VBPJ TechTips #8</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip9.pdf">VBPJ TechTips #9</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip10.pdf">VBPJ TechTips #10</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip11.pdf">VBPJ TechTips #11</A><br /><A href="http://vb.mvps.org/articles/techtips/techtip12.pdf">VBPJ TechTips #12</A><br /><br />I learned sooooo much from these. The loss of these publications is just one of the reasons that VSM is just a shadow of VBPJ. Just for a walk through memory lane I read through some of them, seeing if any of them would apply to C# today. Most of the tips were not transferable, but a few could be.<br /><br />So, here is the first "New" C# TechTip: Originally by Karl E. Peterson<br /><br />How to add an AutoTab feature to textboxes that have a set MaxLength. Connect the textboxes' TextChanged Event to this function:<br /><br /><div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div><br /><div style="background: #ddd; max-height: 300px; overflow: auto"><br /><ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"><br /><li><span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> textBox_TextChanged(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">EventArgs</span> e)</li><br /><li style="background: #f3f3f3">{</li><br /><li> <span style="color:#0000ff">if</span>((sender <span style="color:#0000ff">as</span> <span style="color:#2b91af">TextBox</span>).MaxLength == (sender <span style="color:#0000ff">as</span> <span style="color:#2b91af">TextBox</span>).TextLength) <span style="color:#2b91af">SendKeys</span>.Send(<span style="color:#a31515">"{TAB}"</span>);</li><br /><li style="background: #f3f3f3">}</li><br /></ol><br /></div><br /></div><br /><br />Who knew that the Dot Net designers had included the SendKeys function!?!Lee Saundershttp://www.blogger.com/profile/02660551995265335503noreply@blogger.com2