Welcome to the new NicholasArmstrong.com

There comes a time in every website’s life when it becomes apparent than a newer, more useful version is necessary.  For NicholasArmstrong.com, that time was a year ago.  But it wasn’t until recently that I had the time to undertake a revamp, and what you see before you now is the result.  Welcome to NicholasArmstrong.com – version 2!

The old version – NicholasArmstrong.com version 1 – is still available for history’s sake at http://v1.nicholasarmstrong.com; however, since I’ve upgraded to a newer version of WordPress and rolled forward all of the version 1 era posts, all of the old links should still work and it won’t be necessary for anyone to actually use version 1.  If you notice anything missing, please do let me know.

As part of the revamp, I’ve changed the organization a little bit.  My career portfolio has been updated heavily edited, and now resides at http://www.nicholasarmstrong.com/portfolio.  I’ve removed the references section (newer references are available directly from me), and the work projects and samples section has been merged with the top-level projects category, since it seems to fit better with that content.  Employers and Education have both been completely rewritten into the new employment history and academic history pages, with slightly less content but, I think, a much better presentation (with pictures!).  Outside of that, it’s pretty much the same; the projects section has a slightly larger amount of content, the about page has been updated, and the front page now features the last 3 posts instead of just a generic message from me.

My goal for this revamp was to use existing technologies to produce a highly functional web presence, and I hope I’ve achieved that goal.  Version 2 is built once again on the WordPress blogging engine, and this time uses the Thematic Theme Framework as a base for its style.

While I was developing, I also came across the excellent YSlow and Google Page Speed plugins for Firefox.  YSlow in particular made a surprisingly huge difference to how fast this site renders; both tools give you a list of things to fix to ensure your pages load as fast as the Yahoo!/Google homepages do.  This site isn’t quite that fast, but reorganizing my CSS and Javascript and aggressively setting caching headers should make things reasonably snappy – and a surprising amount better than before I started! (now, if only my hosting provider wasn’t on the west coast…)

One other thing to note: if you have any problems with the site, please do let me know by sending an email to ‘contact’ at this domain (nicholasarmstrong.com).  I’ll be tweaking a few things over the next couple days, too, so if you see a couple minor things changing, don’t be alarmed.

Finally, there’s a small bit of new content available as well; primarily, posts on alternative uses for XAML, as well as one with tips for writing work reports.  Now that the new site is up and running and allows me to do things like post code (which the old version struggled with), I hope to get into a somewhat more frequent posting rhythm, and not leave the site dormant for months!

Enjoy!

Nicholas

Posted in Miscellaneous | Comments closed

Writing an Excellent (Software Engineering) Work Report

Writing a work report is something that students in co-op at the University of Waterloo will do a handful of times throughout their degree.  Unlike the literal interpretation of “work report”, for engineers these reports require the analysis of a situation the student encountered over their work term in order to evaluate their engineering judgment rather than a blow-by-blow description of what a student did on a particular co-op term.  As a report, these milestones also measure a student’s ability to communicate effectively and persuasively, a skill that is just important as knowing what the correct/best answer is.

Recently, I’ve been employed to mark some of these work reports for the Software Engineering department, and through reading and marking these reports I’ve seen many students struggling to grasp the goals and characteristics of a good work report.  There are detailed guidelines for the writing of these reports (the software engineering guidelines are here), yet many times these guidelines are misinterpreted or ignored.  Some of the guidelines – primarily formatting and grammar – generally impact only the professionalism of a report, while others – namely the need for clear and accurate analysis – can result in an unacceptable work report that no amount of eloquent wording can save.  It’s a shame to see well written work reports that show a significant level of effort went into their construction require resubmission because that effort was focused on the wrong areas.

To combat this, I’ve put together a list of things to consider when writing an engineering work report, explaining some of the major areas that students go wrong and my theories on why the guidelines are the way they are.

Make your problem description explicit

All work reports describe a problem that needs to be solved.  Make this problem explicit in your description, don’t dance around it for a few pages and assume your reader will have gathered enough hints to make an educated guess – if they guess wrong, the rest of your report makes little sense.  Come right out and say it (and explain it afterward if you feel it necessary).

Know the difference between criteria, constraints, and requirements

A criterion (N.B: the singular of ‘criteria’ is ‘criterion’) is a metric one can use to measure the ‘goodness’ of a particular alternative, specifically one that can be used to compare alternatives.  Direct measurements like run time, for instance, make great criteria – if algorithm X takes twice as long to run as algorithm Y, then it’s reasonable to conclude that Y is twice as good as X (you can also use logarithmic scales).  Other items can be used for criteria as well – ‘feature set’ is a common one – but it is critical that you can objectively compare two alternatives using them.  For instance, using ‘feature set’ as a criterion and counting up the features of two competing products is not acceptable – you need to establish a list of features that you care about in your scenario, and then count how many of those features that each product has.

A constraint establishes the boundaries of the solution space, that is, it identifies which alternatives are worth considering.  A simple example of a constraint is ‘the solution must run on Windows’.  Unlike a criterion, these are black and white decisions; they are met, or they are not, there is no range.  They are also hard boundaries – any alternative that violates a constraint is not a valid alternative and should not be included in the report.  It is not strictly necessary to have constraints, but they are useful to eliminate large numbers of potential alternatives to focus your report on a specific few.

Some items are both criterion and constraint, though this is something that needs to be clearly identified.  An example of this would be the colour of a new car; blue, green, and grey might be the only acceptable colours (constraint), while blue was preferred over the others (criterion).  You can then use colour as a constraint to eliminate alternatives, as well as to measure the ‘goodness’ of the alternatives that remain.

A requirement can be a criterion or a constraint (or a mix of both), so you still need to understand the fundamental difference between these two concepts.  Most of the reports I’ve seen that take this approach end up confusing themselves and start measuring alternatives against constraints.  I’d recommend against writing your report this way, as the potential for confusing yourself – and confusing your reader! – is pretty high.

Justify your choice of criteria and their relative importance

Buying a new car based solely on colour is not a good idea, and the same concept applies to work reports: make sure that the criteria you choose cover all of the important aspects of the area you are investigating, and if there are criteria that a reasonable reader would expect that you have excluded, explain why they were excluded – or why the chosen set of criteria is sufficient to make a defensible conclusion.

Furthermore, if you combine criteria to form a single measure of ‘goodness’, justify how each of these criteria relate to each other in importance (to continue the previous example, when buying a car one would expect the ‘cost’ criterion to outweigh the ‘colour’ criterion by a reasonable margin).  In some cases, you will have obtained these weights through some internal process – for example, you obtained them from the logs of a current environment, or they were given to you by a manager or collegue; in general, simply explaining how they were obtained (“we performed a series of tests, and determined the weights should be…”) is sufficient.  Your readers need evidence that these weights were obtained in a reasonable fashion and not concocted to favour one particular outcome.

Alternatives are a requirement

The fundamental act of engineering design is making choices – and to make a choice, you need a set of alternatives to choose from.  Since the work report is designed to evaluate your engineering judgment, making decisions without alternatives is unacceptable.  The most common occurrence of this is in the ‘we did this, and it was good’ reports, reports that basically summarize a student’s work term and then tack some numbers on the end to show that what the student did was good.  That’s not a decision!

One way to fix this is to choose between ‘doing nothing’ (e.g. keep the current solution) and a new solution; this approach still does require you to consider different alternatives if they exist, does not apply to ‘synthesis’ style reports (which evaluate multiple decisions with a unique set of criteria and alternatives for each), and needs to be presented in such a manner that bias is eliminated (indeed, doing an analysis and finding out that the best alternative is ‘do nothing’ is a completely valid result).  Having multiple alternatives usually results in a better report (there is less opportunity for a ‘newer is better’ bias since most of these reports do not include the ‘do nothing’ option), but is not actually necessary – and even when evaluating many alternatives, ‘do nothing’ remains a valid alternative in most scenarios.

Analysis without (valid) alternatives is useless

As in the previous point, simply discussing a decision, or set of decisions, without presenting alternatives for those decisions is useless – it does not show engineering judgment.  Further to this, it is important that your alternatives are actually valid, that your alternatives actually have merit.  My grad supervisor tells a story involving two alternatives a student presented for copying a database table: copy-by-row and copy-by-column.  The student correctly concluded (after some analysis) that copy-by-row was better than copy-by-column, but any person knowledgeable about the structure and organization of a database would know that trying to copy by column is ludicrous – it would be orders of magnitude slower in all cases I can think of!  Similarly, presenting an O(n!) algorithm as an alternative to an O(n) and O(n log n) just to ensure you have 3 alternatives is similarly useless; if an alternative is not competitive with the other alternatives presented, don’t include it.

Analysis without criteria is meaningless

I have read a couple reports that attempted to analyze a set of alternatives without well defined criteria.  This usually results in a discussion of the advantages and disadvantages of each alternative without any real structure for the analysis: ‘Advantages: alternative A is blue, alternative B smells good and is red.  Disadvantages: alternative A is heavy, alternative B is old.’  Which one is better, alternative A or B?  With the information given, it is impossible to decide – we would have to know the relative importance of colour, smell, weight, and age to make any determination at all; we’d also have to know a scale for each of the values (is blue better than red?) as well as the missing values (the smell of A was never mentioned).  Unless you have a set of well-defined criteria, any analysis you perform is meaningless.

The ‘throw everything against the wall and see what sticks’ method is another common result of not having a well defined criteria; since the author does not know what to talk about specifically, they talk about anything and everything in the hope that their reader will get the same gut feeling they have for which one is best and therefore accept their conclusions.  Not only is it not a valid form of analysis, but you are just as likely to confuse your reader with random facts that have no relation to your so-called analysis.

Analysis without numbers is risky

Though it is not required until the the third and fourth work reports, analyzing alternatives quantitatively is one of the best ways of convincing your reader that what you say is correct – it is very hard to argue with numbers!   Unfortunately, many software engineering topics do not readily lend themselves to quantitative analysis; measuring the quality of one product versus another is a difficult task to do numerically.  There are ways of doing so – a computational decision making strategy, in which qualitative values are converted into quantitative values as the analysis is performed is one example – but the best way is to spend time exploring a number of different topics before settling on one to write your report on.  It is possible to pass on the basis of qualitative analysis alone, especially for the earlier work reports, but it takes a lot of work and some sort of formal analysis structure to pull it off (and a sympathetic marker).  I would not recommend it – if you’ve found a topic you can only analyze qualitatively, find another topic.

Computational decision making strategies are not ‘plug ‘n chug’

The common response to the ‘quantitative analysis’ requirement is to turn a report that relies on some qualitative analysis into a quantitative one by means of a computational decision making strategy.  This is a reasonable approach to introduce both a formal decision making structure and some quantitative data into your report.  You cannot do this willy-nilly, however; you must explain how this transition occurs and justify that the results of this transformation do not affect the results of your analysis.  If you analyze your criteria without using a standardized scale, then performing a set of operations on the numbers generated for each result has no meaning.  If you are incorporating criteria measured in different units (e.g. ‘software quality’, a qualtitative value, and ‘run time’, a quantitative measurement), they cannot be combined directly until all measured values are converted to a unitless values through a process you define and justify.  If you do not justify the weights with which you combine criteria, the result is meaningless.  If you discuss each criteria without comparing the alternatives and generating a number, and instead just tack on a decision making chart at the end, the result is meaningless.

Using a computational decision making strategy can work really well – but your reader needs to be able to have visibility into how each metric was obtained and how the results were combined for the results to be valid.  Simply plugging numbers that were pulled out of thin air into a table does not show analysis nor automatically ‘work’; you need to justify your use of such a process.

Be precise in your wording

The hallmark of a great technical report is that each claim it makes can be independently and scientifically verified.  In a work report, students are not held to the same standards as researchers are – statistical significance, error bars, and sensitivity analysis would improve the rigor of a report, but are not necessary – but it is still important that everything you say is technically correct and unambiguous.  Phrases like ‘the process should complete in a reasonable amount of time’ are precisely the opposite; as a reader, I have no idea what ‘reasonable’ means in this context.  Without a measurable quantity, I cannot tell whether this constraint is met, regardless of the quality of the analysis.

In addition, be aware of the ‘slightly pregnant/mostly dead’ trap.  Pregnancy and death are absolutes; one cannot be slightly pregnant or mostly dead, one is or one is not pregnant/dead.  While these topics (pregnancy/death) tend not to appear in technical reports, there are plenty of quantities that are similarly absolute and should not be accompanied with a modifier.

Avoid making claims without data

Stating that ‘it is your belief that…’ or ‘it is the belief of the development team that…’ are not valid technical conclusions.  Faith is not a substitute for scientific data in a technical report; I cannot independently reproduce or verify belief-based statements.  If a statement cannot be verified, then it carries no weight in a technical report.  Present data to support your claim, reference an external source, or do not make the claim.

Implementation details are unnecessary

I hope by this point that you have realized that the purpose of the work report is the engineering analysis it contains.  Including details on how a particular solution was built usually is not necessary for the reader to understand your analysis, and thus is not important (a big hint: if you start writing a section after analyzing your alternatives an selecting the best one, stop writing.  You don’t need it.).  While it is unlikely that you will lose marks for including implementation details, including these details takes space that could be used for analysis instead (remember the 20-page main body limit).  If the analysis you do in the space you have isn’t sufficient for credit, then you will not pass the report even if your implementation section is perfectly written – it just does not matter.

Define your terms, and have a glossary

Every time you introduce a term that might be unfamiliar to your reader – who could be in a completely different segment of software engineering than you – be sure to define it and place it in a glossary.  It is really easy to write a report for your co-workers that assume knowledge of certain internal systems, but your reader almost certainly will not have the same knowledge.  Without these definitions, it can be incredibly difficult to figure out what it is you are talking about.

Furthermore, once you’ve defined a term, stick to it.  If it is AJAX when you define it, stick to it – don’t start calling it Asynchronous Javascript And XML halfway through the report, or start calling it by the name of the framework you’re using to accomplish it.  Choose whatever works best for your report, and use it throughout.

Follow the guidelines

This one should be obvious, but the most important advice I can provide is that you should follow the guidelines.  They are very explicit in every aspect of what a work report should contain, where it should contain it, and how it should be formatted.  It’s a shame to lose marks for not formatting your headings right, placing table citations under instead of above the table, not including your conclusions and recommendations in the executive summary, introducing new data in the conclusion or recommendations sections, making conclusions or recommendations that are not supported by the body of the report, etc.  Before you submit, be sure to read through the guidelines and make sure that you are following them all, and have a friend proofread your report for spelling and grammar.  It’s a shame to lose marks for a lack of professionalism when most of the items listed in the guidelines are really easy to fix.

In Conclusion…

… writing a work report is not an incredibly arduous task, and the markers are not out to get you.  As long as you keep in mind that you need to be clear and precise in your writing, need to include alternatives, demonstrate engineering judgment by analyzing a situation using an established set of criteria, you’ll do fine.  Without showing that judgment, however, you will find yourself resubmitting your report in pretty short order.

Posted in Waterloo | Tagged , , | Comments closed

XAML: Not Just for UI

XAML is somewhat of a niche language: developers outside of the .NET world rarely have heard of it, and those that have heard about it – .NET developers or not – often treat it as a language used exclusively for UI design.  So it’s mostly those of us in the XAML niche – those that write user interfaces for a living – that know its secret: XAML itself has nothing to do with UI.  And it can be rather useful in other scenarios if you know to use it.

Why?  XAML is a declarative, strongly-typed .NET language; its simple definition contains no mention of UI whatsoever.  XAML’s key feature is that it makes it easy to declare large numbers of objects rapidly, and allows the composition of these elements into tree-shaped object graphs.  Granted, XAML was built alongside and for WPF – which itself was built on the assumption that you could build complex user interfaces by creating a graph of objects – and so it is a natural fit for WPF, but there are other scenarios that also need to describe large object graphs, and XAML works just as well in those cases as it does with WPF.

Today, Workflow Foundation (WF), a part of .NET 3, already uses XAML to serialize its workflows.  Why?  A quick glance at Rob Relyea’s article on the benefits of XAML provides some clues – XAML describes data in a concise, but human readable way; it is useful for many different types of data; and it’s toolable.  I’d add that it’s also incredibly easy to work with – a call to XamlWriter.Save() is all that’s necessary to serialize an object graph in many cases, and the reverse is the same with XamlReader.Read().  And it’s these very same things that makes it useful for non-UI .NET developers, too.

A Concrete Example

I worked on a project recently which required testing against a reasonable amount of data.  The application would traditionally create, save, and load this data through a variety of methods, but for testing we wanted to be able to fill up the  application’s data model quickly without manually creating test data each time.  It was also important to us to have a couple different sets of test data, so that we could test a variety of different scenarios (many items, few items, big items, blank items, etc.), and being able to store these tests in source control – and merge them intelligently – was also high on our list.

Their are a couple different approaches that we could have taken:

  • Type out all of the data model objects in C# and conditionally compile them into the application
  • Serialize the data model at some point in time, and then load it back in

Of course, each of those had their own problems:

  • C# is quite verbose for typing out large number of objects, we can’t easily grab a snapshot of an existing data model, and conditional compilation with multiple test sets could get tricky
  • Serialization doesn’t handle nested objects well, is incredibly verbose, and requires an infrastructure to serialize and de-serialize everything

Or, I thought, we could use XAML:

  • The data model could be automatically saved at any point in time
  • It’s strongly typed and already tooled, so when we edited a file in Visual Studio, Intellisense would list the legal values for each parameter
  • Everything has a default value unless manually overridden, making editing the test sets easy
  • Multiple test sets just meant multiple XAML files for us to choose from when loading
  • The loading and storing infrastructure is trivial

Making it Happen

There are many ways to write a test data loader; the way described here is just one of them.  It comes in two parts:

  1. A C# class containing the XAML loader, which describes what data is stored in the XAML file, and
  2. A set of XAML files containing our objects

The C# Loader

The C# loader class has two purposes; one, describe the structure of the data stored in a XAML file, and two, perform the actual loading of a XAML file.  While the first part isn’t strictly necessary – a XAML file can represent any data type and doesn’t require a new definition – none of our existing classes fit what we wanted to do.  Our data model root had multiple functions, and was only going to be partly rehydrated with the test data; the rest it would derive from the loaded data and actions taken by the tester.  The test data we wanted to load in our case was a set of devices and set of locations; so we added fields and properties for these items in our loader class:

/// <summary>
/// Class used to load test objects from a XAML file on disk; also, a nominal schema for a XAML test file.
/// </summary>
[Serializable]
public class TestLoader
{
    private DeviceList devices = new DeviceList();
    private LocationList locations = new LocationList();

    public DeviceList Devices { get; }
    public LocationList Locations { get; }
}

An important thing to note here is that by assigning an empty list to each of the fields, I’m setting the default values of these items if they don’t get set from XAML. In XAML, all properties are "optional"; your data model needs to handle this condition (there are some things you can do to ensure certain values are set, but it’s a discussion for another time – note also that the XAML loader can set properties in any order). Also, we’ve got a public property for each of the fields we want to load; the XAML loader will need this later.

The final portion of this class is a static method that, when passed a XAML file, loads the file and returns an instance of itself to the caller (exception handling excluded for brevity):

/// <summary>
/// Loads a XAML file from disk and returns an instance of this class.
/// </summary>
/// <param name="location">The location to read the XAML file from.</param>
/// <returns>An instance of the TestLoader class, containing the objects described in the XAML file.</returns>
public static TestLoader Load(string location)
{
    return (TestLoader)XamlReader.Load(new XmlTextReader(location));
}

And that’s it! If we pass the location of a correctly formed XAML document to TestLoader.Load, it will return an instance of the TestLoader class with TestLoader.Devices and TestLoader.Locations filled from the XAML file. Neat!

The XAML Test File

The XAML test file is even easier: just type out (or save out) the objects you want in the test set (xmlns definitions removed for brevity):

<TestLoader>
    <TestLoader.Devices>
        <Device Name="Lamp" LocationId="4">
            <Attribute Name="Bulb" Power="150W"/>
            <Attribute Name="Bulb" Power="60W" Position="2"/>
        </Device>
        <Device Name="Clock" LocationId="4"/>
    </TestLoader.Devices>
    <TestLoader.Locations>
        <Location Id="4" Name="Den"/>
    </TestLoader.Locations>
</TestLoader>

And that’s it!  As you can see, all we’re doing is creating an instance of the TestLoader file by describing it declaratively in XAML.  Loading that file will load in two devices into our TestLoader instance’s Devices property, one of which has attributes (even though we didn’t explicitly tell it we were saving/loading attributes, the XAML loader just does it on its own – since it is statically typed, it knows how to interpret nested types).  For values we didn’t specify, the default values will be used.  I highly recommend editing the XAML files you create in Visual Studio; the XAML editor in VS will provide you will Intellisense for the XAML files you create automatically, so you can pick your enum values from a list, see what object types are expected at various points, etc. – all of the things you expect from Intellisense!

Some Final Notes

I hope you can get a good appreciation of how easy XAML makes it to load data from the discussion above.  If you’re interested in doing this in a project of your own, examine part 2 of this article for some of the tricky details that you need to know to get this working right, and how to build your XAML files automatically from existing in-memory objects.  And there’s also full sample code with part II, so head on over and check it out.

And above all, keep this technique in mind the next time you need to load or save data; using XAML allows you to structure data, load and store it easily, and allows third parties (like Visual Studio) to support your file format!

UPDATE (18/07/09): Thanks to Rob for his help minifying and clarifying my XAML.

Posted in WPF | Tagged , , | Comments closed

Nicholas on Channel 9!

Welcome to everyone coming across this blog after seeing me speak with Adam Kinney about photoSuru, the application I was building while at Microsoft this past year.  If you haven’t seen the video yet, you can check it out here.

My regular readers (yes, all… ZERO of you) will by now have noticed that I haven’t updated this blog in quite a while, in large part due to working on photoSuru and having a jam-packed school schedule.  I’ll get back to more frequent posts on WPF topics soon, but in the meantime, check out photoSuru – a photo viewing application built entirely in WPF with full source code so that you can remix it as you see fit.  If you just want to check it out, follow the instructions at www.photosuru.com; for source code and developer documentation, browse over to www.windowsclient.net.

I’m very interested to see what the community can come up with based on the photoSuru code – we’ve already seen a couple neat applications being built with it, but there’s plenty more possibilities – catalog browsers, integration with existing photo sites, or even a better storefront for an online store – so give it a shot!

- Nicholas

Posted in Miscellaneous | Comments closed

The "I didn’t know it could do that" WPF Post

Flower in one of the Microsoft gardens At the end of my last co-op term, I was in a good position.  I was a pro at WPF — I’d spent 4 solid months working on a WPF application in the financial sector, and was probably the best WPF developer on the team — even though the others on the team had been working at it longer.  And with WPF being such a new framework, me having such a great amount of experience with the framework meant more interviews for me!  One thing led to another, and I eventually found myself on the WPF team at Microsoft.  And looking back on it now, boy was I ever wrong.

I’ve mentioned before that WPF makes it easy to do things once, but that if you don’t do it right, scaling things up will kill you in the end.  And the more I learn about WPF, the more I find that’s the case — but I covered all of that already.  Rather, I want to want to briefly sketch out some of the things I’ve discovered recently that make a big difference in the grand scheme of things, and that, without actually seeing others do them, I never would have realized WPF could do.

Before I start, I just have to give a big shout out to the guys & gals who wrote all of this stuff in the first place.  Almost daily I find out about new ways of doing things (or ways of using old techniques in a new way), and every time I do it seems as though someone, somewhere has anticipated some esoteric situation that I happen to find myself in, and a few lines of code makes the problem go away.  It never ceases to amaze me — and this has been going on ever since I started fiddling with WPF, so as you can imagine there is a significant number of these scenarios.

Navigating to an Object

After seeing this one in practice in the Syndicated Client Experiences Starter Kit, I’ve fallen immediately in love with its simplicity.  On my first project with WPF, I got really good at wiring up pages to specific sections of our data model and writing code to switch the page in view and thereby have a different look at the data — a very ASP.NET way of doing things.  In the SCE kit, however, they’ve taken a simpler approach: bind an object — any object — to a container on the screen, and switch the object around as necessary.  WPF’s default templates take care of the styling and updating, making that object as complicated or as simple as is desired.  And there’s no passing values back and forth — this is the object, so you can always do anything you could to the original object.  While it doesn’t seem to be much of an improvement at face value, it actually makes a huge difference — you can, at any point, throw a different object into the UI container, and poof! the correct UI appears.  There’s no parsing the object to figure out where to go next, and if you’re smart about things, you can throw everything into a NavigationWindow or Frame and get journalling (back/forward history) for (almost) free as well!  Neat!

Commands

Users switching to WPF from WinForms or ASP.NET will be forgiven for this mistake (I made it too), but if you’re still using event handlers to implement your UI logic, you’ve got to read this now.  While there’s a bit more code to write a command instead of a Click() handler, the benefits far outweigh the extra code.  Using commands, you can completely — yes, completely — divorce the UI styles from the logic behind the UI.  It’s a pretty neat thing to see when you radically alter the UI for an application and everything still works, as I had the opportunity to do a couple of times recently.  I remember the days when a minor change could cause massive damage because of Click() handlers; and yet, I don’t think I’ve ever broken a UI due to a bad command.  Moreover, using commands has other benefits as well.  Want a keyboard shortcut or tablet gesture for that button?  No problem — just call the same command.  Want to automatically disable all keyboard shortcuts, tablet gestures, and UI bound to a command when it can’t be executed?  A breeze — write a one-line CanExecute() handler for the command, WPF does the rest.

Decorators

My upcoming fourth year design project includes a UI component, and (surprise, surprise) I’m the group member writing it.  I had prepared a mockup of a particular UI screen in Photoshop, and with the combination of effects I had applied to get the perfect look for the UI containers, redoing the work in XAML for WPF wasn’t looking too thrilling — and was potentially slow performing as well, or at least it would be until hardware accelerated bitmap effects are available in WPF (which is on the way).  I decided to slice up the Photoshop image and use that instead, but it would have meant a lot of repetitive code just to add a fancy border.  But WPF’s got it covered — a custom Decorator is surprisingly easy to write, and it also drops the number of UIElements in the visual tree so it’s faster, too.  Watch for code here in the future!

CompositionTarget.Rendering

I’m not going to go into much detail here, but if you were ever wondering how some controls create their own physics engines for animation?  The answer is CompositionTarget.Rendering, which is an event called by WPF every time it has the chance to render a frame.  Simply compute how much time has passed since the last frame (so that animations don’t slow down on slow machines), transform your objects as necessary, and call the problem solved.  It’s faster (performance-wise) than WPF animations, and can do some pretty spiffy effects.  Not useful very often, but it’s a pretty neat trick when you’ve got an opportunity to use it.

Custom Panels

I’ll admit: custom panels are hard.  I had avoided writing them as long as I could, but eventually came across a situation where I didn’t have a choice.  But with Dan Crevier’s excellent coverage of the topic (he pulls some IScrollInfo material from Ben Constable), it’s actually not all that difficult — long, but not difficult.  Not something you’d do regularly, but every so often, customizing a panel can really give your application that extra bit of polish — or performance, in the case of virtualizing panels.  And it’s pretty trivial once you’ve got the panel running to add animation and other fancy effects to really push things over the edge.

Attached Properties

If there’s one thing I don’t know how to use yet, it’s attached properties.  Well, sure, I use them — I just haven’t figured out how they can save me time or produce a cleaner solution yet.  But looking at some of the posts on them… it appears they are pretty exciting!  They’re next on my list of things to attack, so I encourage you to have a look too and see how they can help in your projects.

More to come…

I’m going to end this post here, but there are many, many more neat features that I’ll try to write up in more detail in the future.  In the meantime, I encourage you to check out the Syndicated Client Experiences Starter Kit to see some of the neat features they’ve built into the application that make it really easy to work with.  There’s o
bject navigation (as well as a neat solution to journalling in keep-alive mode using weak references), plenty of commands, quite a number of custom controls, a View-ViewModel-Model architecture (more on that in the future, but needless to say, it’s the best way to write high-performing, maintainable WPF applications), and an interesting multi-template layout.  In short, tons of good stuff.  Have a look!

Posted in WPF | Comments closed