February 8, 2008

Check this out... a designer protests a design challenge of updating a hearse -- and it backfired in the worst way:

DOA Design at Design Matters.

February 6, 2008

I've blogged about IValueConverters and WPF many times in the past:

I've got another. This new one may seem a bit obscure, but it has proven useful. Here's what I wanted to do: conditionally, based on the enabled state of a button, swap between two different images, without special code, and without needing to use a style or a template; ideally the solution would not require an events or triggers.

So, I created the ConditionalStringConverter:

 [ValueConversion(typeof(Boolean), typeof(string))]
  public class ConditionalStringConverter :IValueConverter
  {
    /// <summary>
    /// Converts a bound boolean value to a conditional string value.
    /// </summary>
    /// <param name="value">The boolean value (as a Boolean)</param>
    /// <param name="targetType">(ignored)</param>
    /// <param name="parameter">A string of the following format:
    ///    {"value" Matches against this Boolean Value: True or False}?
{Return This Value if matches}:{Return this value if no match}
/// For example: True?BackBtn.png:BackBtnDisabled.png /// If the bound boolean property is True, this converter returns
BackBtn.png. If False, it returns BackBtnDisabled.png
/// </param> /// <param name="culture">ignored</param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture) { if (string.IsNullOrEmpty((string) parameter)) { throw new ArgumentNullException(
"Converter Parameter must be specified when using
the ConditionalStringConverter."
); }

string[] condition = ((string)parameter).Split('?');
if (condition.Length != 2) {
throw new ArgumentOutOfRangeException(
"Converter Parameter improperly specified in ConditionalStringConverter."); }

string[] values = condition[1].Split(':');
if (values.Length != 2) {
throw new ArgumentOutOfRangeException(
"Converter Parameter improperly specified in ConditionalStringConverter."); }

if (value is Boolean) {
bool compareValue = Boolean.Parse(condition[0]);

if ((bool)value == compareValue) {
return values[0];
}
else {
return values[1];
}
}
else
{
throw new ArgumentException(
"ConditionalStringConverter converts only booleans", "value");
}
}

public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}


Before I walk through my simple solution, here it is in use:


<Button
    x:Name="btnBack"
    DockPanel.Dock="Top"
    IsEnabled="{Binding Path=IsNotAtRoot}"
    Click="btnBack_Click" Style="{DynamicResource ImageButtonStyle}">
   <StackPanel
        Orientation="Horizontal">
       <Image
            Source="{Binding Path=IsEnabled,
Converter
={StaticResource conditionalConverter},
ConverterParameter
=True?BackBtn.png:BackBtnDisabled.png,
RelativeSource
={RelativeSource AncestorType={x:Type ButtonBase},
Mode
=FindAncestor}}"
            Height="24"
            Width="24" />
       <TextBlock
            VerticalAlignment="Center"><Run Text="Back"/></TextBlock>
   </StackPanel>
</
Button>

The important part of the example that uses the new value converter is right here:
ConverterParameter=True?BackBtn.png:BackBtnDisabled.png,

Based on the boolean binding, the value converter compares the value of the binding to the boolean value specified as the converter parameter. If the values match, the value converter returns the first value. If it does not, it returns the second value. If you're familiar with the C# conditional operator (?:), this should be familiar syntax.To make the image swap, I resorted to using a RelativeSource binding with an AncestorType of ButtonBase.

image


What's nice about this solution is that the Image's Source parameter accepts the String file name and happily converts it as necessary to the image (which in my application is a resource).And no, I'm not done with the button yet -- so it's a bit ugly.


image

February 3, 2008

Binding's in WPF can make quick work of getting values from object properties.

I've created a class with a property:

    public XmlElement SelectedVideo
    {
      get { return _selectedVideo; }
    }

This Property is  of Type XmlElement. The XmlElement it binds to typically is structured like this:

<Video title="Anonymous Methods" source="Data\anonmethods.wmv" 
timecode="00:01:00" />

With a tiny bit of binding magic, I can easily fetch the title from the element and display it within a textblock:

<TextBlock Text="{Binding Path=SelectedVideo.Attributes[title].Value, Mode=OneWay}"

Since this is a read-only XmlElement, I've set the Mode to be OneWay (as it can't be updated via the TextBlock). Since the element may change, I need to use OneWay binding. OneTime wouldn't work as the SelectedVideo element may change.

The slick part is that the binding syntax allows me to use the indexer on the Attributes object. The only odd thing is that it doesn't need any quotation marks or delimiters.

I'm not using XPath bindings here because I'm not binding directly to an Xml Data Provider in my application (not always at least).

February 1, 2008

When a web site is interested in your personal information -- just for the purposes of interacting with them, how much of it do you provide honestly? (Of course, there are perfectly legit reasons for needing things like your address and phone if you're placing an order).

Imagine if every department store you walked in required you to fill out a form with your personal information, provide a password, and sign up for a few newsletters? Wouldn't you shop elsewhere?

What If every blog you went to required the following to add a comment:

image

Would you ever bother?  Or would you provide mostly fake-data?

I'm amazed by the number of members on zdnet (judging by the comments left on some of the blog posts). My interest in adding a comment this morning dropped to zero when I was asked to give out all of this information.

"Required fields are marked with an asterisk (*)." It should have been inverted: non-required fields are marked with an asterisk. The only field that isn't required practically speaking is a second address line.

But, there's more! You get the privilege of being added to their important newsletters!

And, so that you might miss it, down at the bottom of the subscription list (after a long list of unchecked newsletters):

image

They've handily pre-checked one for "offers from our premier enterprise sponsors." Otherwise known as opt-in spam.

Finally, to sign up you must agree to their privacy policy and "terms and conditions" -- which total 4,863 words.

No thanks ZdNet.

January 31, 2008

imageDue to a small usability issue on the Mono web site, users were downloading versions that were more than 2 years old!

Only 5% of the Mac downloads were actually getting the latest version, 95% was downloading this two year old version. I don't have my notes handy for Windows, but they were similarly abysmal [Update: found the notes, they were 95% as well].

Read more about how this happened here.

So, if you had a recent experience with Mono -- you might want to check to see if the version was current!

(Mono is an open source implementation of .NET for client and server applications).

January 30, 2008

Did you know that the original Palm Pilot had a screen resolution of only 160 x 160 pixels? That's a total pixel count of only 25,600! Every pixel used had to be carefully considered. With all of the pixels we have at our disposal today on the average computer screen (OS X, Windows, Linux, etc.), why does it appear that many pixels are wasted? As the pixel count of screens has increased (and the resolutions and sizes of our monitors), have we become increasingly lazy about software design? For example, many web sites grow slowly wider and taller as the accepted minimum screen size has increased.

Has the average web site really improved at the same rate of pixel increase? Take for example a web site that was designed for an 800x600 screen. I'll ignore for the time being that a web browser, even in full screen mode doesn't use all of those pixels.  There are 480,000 pixels available for the designer.

Now, increase the screen size to 1024 x 768 for a total of 786,432 pixels. That's 288,432 more pixels than was available at 800 x 600! So, clearly the application improved by about 60%! Except the reality of the change is less likely to be such a dramatic improvement.

I'm continuing to read Designing Interactions (previous mention here, and which I highly recommend now that I've read more of the book). The original Palm software team had these simple four design guidelines:

Less is more

Avoid adding features

Strive for fewer steps

Simplicity is better than complexity

Sweet. But, how do you decide where to put features, once you've decided that the features are important? On an 160 x 160 pixel screen, there isn't room for every feature. Many software applications have this problem. Rob Haitani, one of the primary designers of the Palm interface, provided an analogy that can be used even today in designing modern applications that have the freedom of using many more pixels than their tiny predecessor. Think about the way your desk is organized. There are things that you've put out on your desk, and things you've put away. Why is that? The things you want immediately are on top, the rest are tucked away in drawers. If you had to retrieve your mouse from a drawer every time you needed it, you'd be extremely frustrated, but if every time you needed to remove a staple you had to reach into a drawer, you'd wouldn't mind that small multi-step process (and slight delay).  The stapler however, if you use it frequently is more likely a fixture on your desk, so that you can quickly access it.

Of course, the challenge is how to hide functionality that isn't necessary, and how to maximize on the pixels that you're using. That's what makes design hard.

One key is to understand your users and how they work. What would their "desk" look like? Are they frequent staplers? If you continue with Rob's analogy -- how would they feel if you shuffle their drawers and the contents around occasionally during the day? That's what it could feel like to a user if you're moving user interface elements around the screen. Or, what if their stapler is suddenly "disabled" with no context or reason why? Again, more user confusion.

What are some of the best examples of applications that maximize their use of pixels that you've encountered? What are some of the worst?

January 27, 2008

I have no idea what inspired this.

image

See for yourself here. You'll need Silverlight 1.0 installed.

This is in no way any indication of any political affiliation -- or any indication of anyone I may vote for in the primary or general election. I had actually hoped to get more "heads" done this afternoon, but I ran out of time after these two.

The Silverlight code was very simple in this first edition. I added a few Mouse handlers:

rootElement.addEventListener("MouseMove", 
Silverlight.createDelegate(this, this.handleMouseMove));

The handler above was used to move the hand around:

handleMouseMove: function(sender, eventArgs) 
{    
  var hand = this.control.content.findName("hand");
  var pt = eventArgs.GetPosition(null);
  
  hand["Canvas.Left"] = pt.X - hand["Width"] / 2 ;
  hand["Canvas.Top"] = pt.Y - hand["Height"] / 2;
}

The mouse down was even simpler:

handleMouseDown: function(sender, eventArgs) 
{    
  this.control.content.findName(sender.Name + "Bobble").Begin();
  this.control.content.findName("WhackHand").Begin();
},

January 25, 2008

Frustrated by slow, boring presentations, I put together this helpful slide show:

Slide1

Slide2

Slide3

Slide4

Slide5

Slide6

Original files here: pptx (preferred) and ppt.

January 24, 2008

I read this book 6 or 7 years ago after being given a copy by a new development manager while working at Microsoft, and something today reminded me of it -- so I thought I'd recommend it to others (I couldn't remember the author!). I rarely enjoy reading books that are about project management, time management, ... they're so dry that after the first 10 pages, I've lost interest.image

Tom DeMarco's, "The Deadline: A Novel About Project Management" is one of my favorite project management books I've read -- and one of the very few that I've read cover to cover. Even better is that I actually felt like I learned something!

The book kept my interest as it's written as an interesting novel. From the book's "home page":

With his trademark wit set free in the novel format, DeMarco centers the plot around the development of six software products. Mr. Tompkins, a manager downsized from a giant telecommunications company, divides the huge staff of developers at his disposal into eighteen teams -- three for each of the products. The teams are of different sizes and use different methods, and they compete against each other . . . and against an impossible deadline.
With these teams, and with the help of numerous consultants who come to his aid, Mr. Tompkins tests the project management principles he has gathered over a lifetime. Key chapters end with journal entries that form the core of the eye-opening approaches to management illustrated in this entertaining novel.

I lost my copy a few years ago in one of my many moves and always wished I hadn't as I'd enjoy reading this book again.

Definitely recommended. It might just open your eyes to some better ways to manage a (software) project.

Inspired by this post Functioning From: Interface Design, "What is Product Excellence?"....

Technology products often follow a reasonably well understood lifecycle. I just recently blogged about it in a slightly different context.

Donald Norman in this book, in his book, The Invisible Computer puts it this way:

When the technology reaches the point where it satisfies basic needs, then improvements in the technology lose their glamour. Now customers seek efficiency, reliability, low cost, and convenience. Moreover, new kinds of customers keep entering the market as the product matures. In the early phases were the early adopters, those who were willing to gamble on the new technology because they felt the benefits far exceeded the costs. More conservative customers held back, waiting for the technology to prove itself, to become reliable. This is the cycle of market adoption described by Geoffrey Moore in his book Crossing the Chasm (see figure 2.3).

It can be a painful realization for a product developer when the type of improvements and the new functionality shift from a pure checklist of features for early adopters to a more refined, reliable, and elegantly simple product. The message from customers changes from "feature A, B, C must be done, to please make it easier to do features C, D, and E." Shifting from one methodology to another can be disastrous if not handled carefully.

At the very time when a company needs to step back and take a new look at itself, when it needs to reorganize and restructure, the financial story puts severe pressures on its ability to do this. Time is the one thing it does not have. Suddenly, it has to meet market requirements, but the old guard wants to do it by adding yet more new technology, bringing out new products at an ever-faster rate, and fighting the falling revenues by cutting back on the size of the company. It is a tumultuous time. Geoffrey Moore called it a "tornado."3

How does a company prevent this from happening? I've been following a few software products recently current in beta, with an interest in purchasing a few. These products are clearly falling into the lifecycle. I've read the forums and see all of the feature requests from early adopters and promises from the development staff. At some point, in version 2 or version 3 though, the product has ceased to be an early adopter product -- and will likely have crossed over the transition point Donald Norman suggests in his book:

 

image

By the transition point though, most software applications have pages of switches, and options by which the application can be controlled.

For example, Visual Studio 2008:

image

I didn't attempt to count, but there must be hundreds of options within. The vast majority of the options cater to the small percentage of vocal early adopters. I don't change very many options in an new installation any more -- even though they finally added the ability to copy settings from one installation to another.

How does a mature product like Visual Studio "go simple?" Do you risk alienating your early adopters? Do you create two different versions? These are tough questions. For Microsoft and Visual Studio, early adopters are often their "most valuable professionals" these days. Hardly the group you want to push away.

Microsoft demonstrated in Office 2007 that it is possible to rethink a user interface in an attempt to simply it and make it more appealing to the general consumer. The Office team was concentrating on user experience, no longer a feature "war" like they had been fighting for the last 10 years. There was grumbling sure, and complaining, some people resist change at all costs. But overall, it was well received. I still hunt around for a few options occasionally -- but the things I need are generally in the "right" place. It's been long enough since I switched that I've forgotten the struggles of using old versions already.

What do you do when you're already at the curve's transition point? How do you adapt? Hindsight only helps prevent a future reoccurrence -- but even then the tendency of typical software development and design suggests this pattern is difficult to avoid. (If you are a user of the product you sell, it may be easier to avoid).

Once you've hit that transition point, you either need to change, add new products, accept mediocrity, or retire. Change is most painful, but most likely to lead to renewed interest in your product and sales.

In association with Amazon.com