Rediscovering the Obvious

…stumbling in the footsteps of greatness

Archive for October, 2010

EntityCommandShim<T> – Silverlight MVVM helper

without comments

I received a question yesterday around the shim pattern that I used, and I thought I’d clean it up a bit and share it. Again, if you’re used to reading about agile and lean here, this isn’t one of those posts (in case the title didn’t make that clear).

Refresher

The situation I’m addressing is that I have an element in my XAML that uses an ItemsSource (e.g. ItemsControl, ListBox) and want to receive an event specific to one item. This post will assume that I’m working with an items template like this, which will be bound against a DTO or Entity that has a property descriptively named “Value” containing the content to display.

<DataTemplate x:Key="TemplateSelectionItem">
   <HyperlinkButton Content="{Binding Value}" 
   />
</DataTemplate>

Now, whenever the user activates the hyperlink, the “Click” event will be raised. Without MVVM, I’d just add a handler in my code-behind that attaches to the click event and performs the logic. The testability and separation of concerns aspects of MVVM suggest this is a very bad idea. Instead, we should set up something that is called in response to the click. This leads to two options: put handling code on the bound entity, or put handling code in the ViewModel containing the ItemsControl. Since polluting the entity seems like a bad idea for a behavior local to a single view, let’s plan on putting it in in the ViewModel. And, since I like command objects for the flexibility they offer for a wide variety of scenarios, let’s target calling a Command instead of a method. Avoiding Prism-specific code, I’d write something like this:

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding Command}" CommandParameter="{Binding }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

Unfortunately, the “Command” binding will always fail, because the DataContext is currently set to my entity. Well, that’s fine, let’s just use a named source like this:

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding DataContext.Command, ElementName=myListBox}" CommandParameter="{Binding }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

Unfortunately, this is entirely too brilliant to keep working. It’ll work great as long as you don’t modify the ItemsPanel of your ListBox [1]. As soon as you do that, the binding will fail, and it took me far too long to figure out why the first time. Remembering back to my early programming education when I was taught things like “there’s no problem that can’t be solved with another level of indirection”, I decided to just put something in the middle that puts the Command where I need it. Thus the introduction of the shim, or as it’s now called, the EntityCommandShim. The comment prompted me to do some aggressive refactoring of what I was using, so thank you… here’s what it looks like now:

    public class EntityCommandShim<TEntity>
    {
        public EntityCommandShim(TEntity sourceObject, DelegateCommand<object> command)
        {
            Debug.Assert(command != null && sourceObject != null);

            this.Command = command;
            this.Entity = sourceObject;
        }
        public DelegateCommand<object> Command { get; private set; }
        public TEntity Entity { get; private set; }
    }

There’s not much to it. The Command and Entity references aren’t meant to change for the lifetime of the object, so no INotifyPropertyChanged implementation. The passed in Command is just a reference to one declared on the ViewModel, and doing the wrapping is quite simple with a line like this:

            this.AvailableTemplates = service.AvailableTemplates.Select(item =>
                new EntityCommandShim<FilterData>(item, TemplateItemSelectedCommand)).ToObservableCollection();

Once this is done, I’m all set. The ItemsTemplate becomes: [2]

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Entity.Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding Command}" CommandParameter="{Binding Entity }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

and the repeater can be as simple as this:

            <ItemsControl
                ItemTemplate="{StaticResource TemplateSelectionItem}"
                ItemsSource="{Binding AvailableTemplates}"
                >
            </ItemsControl>

Or as complicated as this: [3]

<input:AutoCompleteBox 
    FilterMode="Contains" 
    MinimumPopulateDelay="250"
    ItemsSource="{Binding Clients}"
    SelectedItem="{Binding SelectedClient, Mode=TwoWay}"
    ItemTemplate="{StaticResource ProviderSelectionItem}"
    IsDropDownOpen="{Binding IsSelectionActive, Mode=TwoWay}"
    ValueMemberPath="Entity.Value"
>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding SelectionChangedCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
        <i:EventTrigger EventName="DropDownClosed" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding SelectionConfirmedCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
        <i:EventTrigger EventName="DropDownOpened" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding BeginSelectionCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</input:AutoCompleteBox>

[1] I haven’t tried this with ItemsControl, and I don’t know where this issue comes from… any thoughts? I also haven’t tried this in SL4, maybe it’s fixed? Will check that out soon, and if it works, all of this can be removed, making it a true “shim” in the sense that it goes away when the floor’s fixed.

[2] When I need to synchronize against SelectedItem in a list box, I often use CommandParameter={Binding} so I get the instance of the shim to reassign back to a property that’s Mode=TwoWay bound against SelectedItem.

[3] InvokeCommandWithArgsAction is adapted from http://weblogs.asp.net/alexeyzakharov/archive/2010/03/24/silverlight-commands-hacks-passing-eventargs-as-commandparameter-to-delegatecommand-triggered-by-eventtrigger.aspx and is a way of passing the arguments of an event as the CommandParameter. Check it out!

Written by erwilleke

October 25th, 2010 at 3:15 pm

Posted in Uncategorized

How does Google know this stuff?

without comments

I get this – it’s a satellite picture of my condo building in Indy

image

On the other hand, how do they know where the individual units are inside? (Oh, and they’re RIGHT).

image

And it’s done for the apartments nearby…

image

 

What feed is this from?

Written by erwilleke

October 24th, 2010 at 7:21 pm

Posted in Uncategorized

Silverlight AutoCompleteBox and MVVM

with 2 comments

First, a warning

This is not an introduction to the AutoCompleteBox. If you’re looking for a basic overview of the there’s nothing better than Jeff Wilcox’s intro at http://www.jeff.wilcox.name/2008/11/autocompletebox-missing-guide/. Read that, then come back. It’s where I learned by example.

There’s no direct anchor, but about half way down the page you’ll find a section titled “Building a custom search filter” and I’ll be picking up from there. His advice is “Here’s a sample item filter, set in the Loaded event of my page”, which is the first indicator that this isn’t the way to go if you’re doing MVVM… what follows is a way around that.

Next, the backstory

One pattern I’ve adopted in Silverlight development with MVVM is to introduce a helper object when I’m binding to a ListView or ItemsControl’s ItemsSource property. I call this object a “Shim” because it a slightly hackish way of solving what would otherwise be a much bigger problem creating a lot of rebuilding needs. Essentially, the Shim becomes the new DataContext that sits behind each bound item, becoming a mini-ViewModel that matches the mini-View defined by the DataTemplate/ItemTemplate. My typical need is that I need to accomplish two goals:

  1. Bind to the data in a DTO or Domain Object in some interesting way
  2. React to a user’s operation against that item in some way specific to the data instance.

Unfortunately, markup like this doesn’t work in the ItemTemplate because the DataContext is now set to your specific DTO instance rather than to the original ViewModel instance.

<HyperlinkButton Content="{Binding Value}" 
             command:Click.Command="{Binding ItemSelectedCommand}" 
             command:Click.CommandParameter="{Binding}" />

Instead, I introduce the Shim with an assignment something like this:

this.Clients = insurer.Clients.Select(client =>

    new ClientSelectedShim(client, SelectionChangedCommand)).ToObservableCollection();

and then bind as follows:

<HyperlinkButton Content="{Binding Value}" 
             command:Click.Command="{Binding ItemSelectedCommand}" 
             command:Click.CommandParameter="{Binding OriginalData}" 
             />

The Shim instance simply exposes the provided DelegateCommand as a property, along with the original DTO and often an intended display value. (Thus, I bind to “Value” instead of “OriginalData.Value”).

Overall, this feels like the cleanest of several different approaches I’ve tried to get around this binding issue in Silverlight. [1] I tend to do this using the Prism library, but it’s also applicable to other simple MVVM approaches. For example, the same would apply with using an EventTrigger and InvokeCommandAction to activate the command as such:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
        <i:InvokeCommandAction Command="{Binding ItemSelectedCommand}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers>

Finally, the Point

All this rambling is a lead up to the challenge I hit today: I added a Shim into the list of items used to populate an AutoCompleteBox, because I needed to respond to the user with some item-specific behaviors in the popup that contains the matching values. As soon as I added the Shim, I couldn’t use the simple FilterMode=”Contains”, because it was comparing against the type of the shim rather than the much simpler string I was giving it before. Because I suddenly had a Shim involved and couldn’t dodge the complexity of having a DTO by just yielding the display value any longer, I was forced to use FilterMode=”Custom”. {EDIT [3]} Problem is, MVVM strongly discourages me from writing code anywhere that looks like Jeff’s sample:

MyAutoCompleteControl.ItemFilter = (txt, i) => Stock.IsAutoCompleteSuggestion(txt, i);

The good news is that binding is incredibly powerful, so here’s what I can do instead:

<input:AutoCompleteBox  
   FilterMode="Custom" 
   MinimumPopulateDelay="250" 
   ItemsSource="{Binding Clients}" 
   SelectedItem="{Binding SelectedClient}" 
   ItemTemplate="{StaticResource ClientSelectionItem}" 
   ItemFilter="{Binding ShimFilter}" 
/>

<!—In Resources –> 

<DataTemplate x:Key="ClientSelectionItem">  
   <StackPanel Orientation="Horizontal" > 
      <HyperlinkButton Content="{Binding Value}" 
         command:Click.Command="{Binding ItemSelectedCommand}" 
         command:Click.CommandParameter="{Binding OriginalData}" 
      /> 
    </StackPanel> 
</DataTemplate>

And, in the ViewModel: [2]

public AutoCompleteFilterPredicate<object> ShimFilter 
{ 
    get 
    { 
        return new AutoCompleteFilterPredicate<object>( 
            (str, item) => { return IsFilterMatch( str, item ); }); 
    } 
}
private bool IsFilterMatch(string valueToCheck, object item) 
{

    ClientSelectedShim shim = item as ClientSelectedShim; 
    if (shim == null) 
        return false; 
    return shim.Value.Contains(valueToCheck); 
}


It wasn’t immediately obvious to me, but this definitely lets me put my comparison code in the ViewModel where it belongs while keeping the expression of the UI structure and behavior. Now I can wire the special effects!

 

[1] One of the most promising ways I’ve otherwise tried involved binding using ElementName to get “out of” the ItemTemplate and back to an element on at the parent level, typically the containing list itself. This will work as long as you don’t change the ItemsPanel to a non-default panel. Making that change hits some bug (feature?) in Silverlight I can’t properly characterize and causes lots of pain figuring out what happened. Be warned!

[2] The property has to stay templated to the <object> type or there will be a binding expression error when the View is first bound against the ViewModel… covariance doesn’t apply here. More info here. Second, it appears it must be an actual property, the binding failed when I tried to have a simple field initialized to the Predicate.

[3] After figuring this all out, I did of course come across the incredibly useful ValueMemberPath property, which allowed me to revert to a simpler design for my specific case. However, if you are doing custom filters (especially if you’re checking against multiple properties, which I’ve done in the past), this technique will still be quite valuable.

Written by erwilleke

October 24th, 2010 at 7:07 pm

Posted in Uncategorized

More good ideas or more labels?

without comments

What do you care about?

An off-kilter venn diagram with three overlapping spaces titled Kanban, XP, and Scrum. They all sit superimposed on a much larger circle titled Good Ideas, along with a call to action to focus on what is important, not about the labels.

Written by erwilleke

October 8th, 2010 at 10:45 am

Posted in Uncategorized

Beyond (Measurement)

without comments

Context

At the “Scrum Beyond Software” in Phoenix, Tobias (@tobiasmayer) challenged us to get beyond the words, and I echoed him. Now it is time to put action behind my words!

This morning, my inbox was freshly loaded with an opportunity to help an unknown find a better way of doing things, and it started like this:

Confession: In all my years of software development I’ve never successfully and usefully estimated, tracked, or measured anything.
I get the impression that measurement is one of the keys to improvement.  If that is so, where should we begin?  What useful statistic should we collect first?  What value can we derive from that info?  How can we apply the information to help us do better? – Alan Baljeu [1]

My challenge to myself: answer this without using any loaded words like “cycle time” or “velocity” or “takt time”, and do so in a way that allows the reader to use the results for self-driven, meaningful improvement at a team level. Here we go!

What do I measure?

I’m going to use a basic physics metaphor. For each of the levels, track things as simply as possible at the item level, aggregate for clarity and perspective, manage any single item out of the ordinary as a special case. Keep the results big and visible in the team’s shared space, whether that’s physical or virtual. Please note, there’s nothing really new here, the basic ideas and metaphor have been around longer at least as long as I’ve been doing software.

1 – Position: What’s being worked on, what’s completely done, what’s going to be worked on next (for a very limited scope of "next" ).

2 – Motion: Take the above, add in time dimension: How long did each item take, when did it start, how many other things were being worked at the same time.

3 – Acceleration: Take the above and start looking for changes in the trends over time. If the "how long" is decreasing, and you didn’t do anything intentionally to make it do so, figure out why and (likely) celebrate!

How do I introduce it?

In my experience each of these levels provides its own, distinct benefit if you do them in order. Start with level 1, figure out a way to effectively track it in your team, get people used to seeing it for a few days, and observe the changes it makes in how the team interacts. Tweak how you’re tracking position and ensure the team’s comfortable before you move forward trying to track and use the next layer of information. Typically, this step is a basic physical or virtual task board, although it could be a shared Google spreadsheet or any number of other tooling-based solutions.

Next, start putting dates along with the work. At its easiest, just jot down the day work starts on something, and the day it’s done, then do a “week-day math” subtraction to find out how many days it was actually being worked on. See what this awareness does to the team, how they react, if the information’s in the right spot.  Finally, start tracking those numbers over time. How many things are typically being worked on at once? Does this number seem to be going up, down, everywhere, etc? How about the time things tend to take? Is it getting smaller? How about rework on things that “could” have been right? Is it in balance with the time it would have taken to discover the right way in the first place? Is Quality high? Start mapping the perceptions against the numbers and see if they match up, figure out what patterns are in there.

Throughout these steps you’ll start seeing things you want to change about how you approach your work. Do so! Try things, see if they work, and be willing to put things back the way they were if you don’t like the results. Foster an attitude within the team to make these experiments a Good Thing ™. Treat them as experiments… success and failure isn’t the goal, learning a better way is the goal, and it takes both “success” and “failure” to achieve that learning.

Finally, remember to look back at the old numbers once in a while, and celebrate as a team just how much better the new numbers are, and how far you’ve come as a team.

Good luck!

 

[1] – I normally would avoid applying attribution to something that sounds potentially negative. In Alan’s case, I greatly respect the courage it takes to publically state something like this, and I also recognize that finding a quote is trivially easy and he deserves the respect that courage deserves.

Written by erwilleke

October 5th, 2010 at 11:52 am

Posted in Uncategorized