Feeds:
Posts
Comments

Archive for the ‘Uncategorized’ Category

Unpacking Some Boxes

I was asked to make one final post here when RSS feeds were exposed on the new site. Well, the feeds were always there, just not readily visible on the page. If you were using a browser that was feed aware, it would have detected two feeds on the site. However, that’s not really all that friendly. Not having the usual feed icons on the page was one of those “unpacked boxes” that I talked about. Well, I’ve updated the site design a little, and now those pesky feed icons are prominently displayed.

This time, this really should be my last post on this blog.

Read Full Post »

Moving Again

Yes, I know, it’s not been that long since I moved from Windows Live Spaces to here, and there’s not a lot of content here. However, I’m still moving again. This time I’m going to self host so that I have complete control over the site. So, if you’re following my rantings, follow me on over to http://www.digitaltapestry.net.

Read Full Post »

I’ve Moved

OK, after the rant in my last post, I’ve done it. I’m not going to be posting to this blog anymore. I’m moving over to WordPress at https://digitaltapestry.wordpress.com.

Read Full Post »

Spaces Rant

Windows Live Spaces are driving me nuts. I’m going to be looking for a new home for my blog very soon. I’m that fed up.

I get way too much spam in my comments. Do a Google (Bing) search and you’ll find that this has been a very long standing complaint, and there’s really no excuse for this. The spam I’m getting is very obviously spam, and is guaranteed to be caught by event he lamest of spam filters, but Spaces doesn’t employ any spam filters! Oh, but it gets worse. For much of the lifetime of Spaces there was no way to report spam. The tried to address this, but the result is a pain to the user, and there seems to be no results obtained from reporting the spam. There should be a big SPAM button on every comment when you’re in admin mode. Pressing that button should do numerous things:

  1. It should automatically notify the site administrators as to the wrongful behavior of the user, so an investigation can begin and the user can be banned.
  2. It should delete the comment.
  3. Optionally, it should block the user from ever posting to the blog again (outright banning from all blogs should be done only after investigation by administrators). In this case it should also delete all other comments on the blog left by this user.

Instead, we’re left with having to manually locate a form to fill out with information about the spammer that seems to be ignored, and then manually have to delete every spam comment. Manually deleting those comments is a royal pain. You can’t multi-select, it has to be done one message at a time, and each deletion requires confirmation. In less than a week I’ve received more than 60 spam messages, and deleting all of those is going to waste a lot of my valuable time. What’s worse, it’s all spam that I never should have gotten in the first place, if they’d simply run a spam filter!

Yeah, I’m going to be moving somewhere else. Just got to figure out where.

Sorry for the rant, but I’m in a mood right now!

Read Full Post »

This is just too funny not to share. I’m not going to give exact quotes or setup context, but just go straight for the funny bone.

Peter O’Hanlon: Who is this Major Hack you refer to? Is he in the same battalion as General Exception?

Michael Brown: I think Colonel 32 was also in that division.

Peter O’Hanlon: Along with Private Bytes?

Read Full Post »

I’ve released a Beta for Specificity, so it’s no longer just a source repository. Specificity still isn’t ready for full release. There’s additions to the release I plan to make, including project and item templates. However, I expect the APIs to be stable at this point. Creating a release, including an installer, was important to me. See, it’s going to help with one of the largest complaints I’ve received for Onyx: figuring out which source revision of Specificity to use. In the next day or two, I’ll update Onyx to use an installed version of Specificity, and those issues should be gone.

I’ve had to learn a lot of new tech to make this release. I’m using Wix to create the installer, and that’s not the most intuitive thing to work with. Then there’s the project and item templates that I’m working on. These require a custom wizard to control code generation, since Specificity is compatible with numerous different unit testing frameworks. If I find the time, I’ll try and blog about what I’ve discovered here, but if nothing else, hopefully the source will be useful for anyone else trying to figure this stuff out.

Read Full Post »

Disclaimer: This blog post is theoretical notes about an interesting subject, and does not contain a working solution. I will probably provide a solution in the future, but if you’re looking for one here, you’ll be disappointed.

Glenn Block had an interesting post about the “spirit” of the ViewModel design pattern. If you haven’t read it yet, do yourself a favor and go do so. I’m not going to talk about his subject matter here, really, but there was a very interesting reply in this posting from Ward Bell who’s also got a blog that’s well worth reading. In the reply, Ward talks about simplifying XAML/WPF coding by using convention based programming. In particular, this paragraph in his response stuck out to me:

Maybe we shouldn’t be marking up Person.Name at all. Maybe, if we had an easy way to walk the XAML tree, we could automate the wiring of the binding by letting convention tell us that "Person.Name" is accessible from the ViewModel.

See, the thing is, we do have a way to easily walk the XAML tree.

I’ve been playing around with a couple of different convention based solutions to WPF programming, some of which will see the light of day in Onyx in the near future, hopefully. What I’d like to do with this blog post is explore the idea, describing a concept that could be implemented to do exactly what Ward wants. I’m going to discuss implementation details, but I’m not going to provide code. This is all theoretical and is being presented for discussion purposes.

Ward gives a use case where he has a TextBox that’s been provided an x:Name value. He then says “A one-line wizbang in the code-behind constructs the binding for us … and not just for this TextBox but for every control bound to a property of Person.” First, I don’t like the idea of needing a “one-line whizbang in the code-behind.” I’d propose that instead we rely on an attached property/behavior to do this. Onyx already has the perfect attached property for this: View.ViewModel. The change handler for this attached property can walk the tree to provide our convention based bindings. In WPF we can actually use a trick that would enable us to not even have to walk the tree manually. View.ViewModel in the WPF version of Onyx is marked as an inherited property, so we’ll get change notifications for every child element which means WPF has done the work of walking the tree for us. In Silverlight you’ll have a bit more work to do, and it may be a bit tricky to handle some timing issues, but it’s all very doable.

I’d like to discuss using x:Name as the hook to use for our conventions. I don’t like this, for a few reasons. First, the fact that x:Name creates backing fields for you is something that I don’t care for, unless your intention really is to have a backing field. Second, x:Name is meant to be unique, while there will be several scenarios where we don’t want to be restricted in this manner. So, I’d propose using a special attached property for our hook. I’m struggling with a good name for this one, but for now let’s just call it View.Moniker.

So, now we have everything that’s necessary to do data binding by convention instead of configuration. But we can carry this idea much further. Let’s say we have a Button that we’ve given a View.Moniker of “Save”. If we have a SaveIsEnabled property on our ViewModel, that should be bound to the IsEnabled property of the Button. If we have an OnSaveClicked method on the ViewModel, that should be added as an event handler for the Click event of the Button. If we have a SaveCommand property on the ViewModel, that should be added as a command binding on the Button. You can imagine several other conventions to adhere to, so this should be an extensible concept. Instead of hard coding the conventions, include an ApplyConventions (needs a better name) event that can be hooked into to apply the conventions required by the individual application.

So, what are your thoughts on this?

Read Full Post »

In my last blog post I referred to the Behavior as “your trusty ViewModel bazooka”. Well, if Behaviors are akin to bazookas, I guess services must be akin to something on the scale of the Death Star! Seriously, there’s no problem that can’t be solved by the use of a service. The concept is that powerful. That’s why they are the integral part of Onyx. Every problem that ever came up that I couldn’t find another solution for, services could be used to save the day.

Services?

So, what is a service? This very question got asked on Stack Overflow in response to an answer I gave to another question. Like I answered on Stack Overflow, put simply, a service is an object that provides functionality to be used by other objects. These services are generally provided to the other objects through either the Service Locator or Inversion of Control patterns. Onyx provides a generalized mechanism for this using the Service Locator pattern, hopefully with the hooks necessary to override this to use Inversion of Control instead.

In any event, services are powerful, because they are reusable pieces of code that can be easily replaced with alternative implementations. This means that at runtime they can do all the logic necessary to accomplish your task in a tightly coupled fashion, just as you would have in the old days before the ViewModel pattern using event handlers in your codebehind. Then in your tests you can replace this behavior with test doubles that provide the behavior you need for the test in a way that’s not coupled to any UI.

Message Boxes

Let’s try and make this concrete with an example. One problem that everyone new to the ViewModel design pattern asks about is how you display a MessageBox to the user in response to something that occurs in a Command handler in the ViewModel. You can’t simply call MessageBox.Show, because that’s makes the code impossible to test. This is one problem for which, although there might be alternative solutions, the best solution is to use a service.

The first thing to do when here is to define our service. Since a service needs to be replaceable, we need to use either an abstract class or an interface to define the service. We’ll stick with using an interface.

public interface IDisplayMessage
{
    void ShowMessage(string message);
}

I’ve kept this very simple for this blog post. Onyx actually defines an IDisplayMessage service that’s more complete, allowing you to fully specify all of the optional parameters that you can supply when calling MessageBox.Show, but that would be a distraction to this conversation. OK, the service is defined. Now we need to provide an implementation.

internal class DisplayMessageService : IDisplayMessage
{
    public void ShowMessage(string message)
    {
        MessageBox.Show(message);
    }
}

Again, this is a simplified implementation for the purposes of discussion here. All that our service does is delegate to MessageBox.Show, which is a tightly coupled implementation. That’s fine, because when we use the service, we won’t be tightly coupled, since we can provide a different implementation of the service. For instance, not only can we provide a test double in our unit tests, but we could also decide that instead of display a modal dialog, all such messages should be displayed in a list in a docked message window in our UI, and this change doesn’t require any modification to the ViewModels that use the service.

Next up, we have to supply the service to our ViewModel somehow. We’ll do this by adding a parameter to the constructor, which is the Inversion of Control pattern.

public Window1ViewModel(IDisplayMessage displayMessage)
{
    this.displayMessage = displayMessage;

Then in the ViewModel we can use this service to display a message.

this.displayMessage.ShowMessage(string.Join(Environment.NewLine, this.SelectedDisciples.ToArray()));

Keeping things simple, we’ll just manually supply the service when we create the ViewModel (this is often referred to as “poor man’s dependency injection” since we’re not using a container).

this.DataContext = new Window1ViewModel(new DisplayMessageService());

Keep in mind that everything we did here was the simplest possible implementation that can illustrate how to use services, and not necessarily the best or most maintainable way of doing this. I don’t want to confuse you with the extra code necessary to use a container for either service location or dependency injection, as those are architectural artifacts not necessary to the concept of using services.

So, we declared a service for displaying messages to the user, implemented a version that will display a MessageBox, provided the service to the ViewModel, and used it to display a message. We now have a ViewModel that displays a message in a way that’s decoupled from how the message is displayed and thus decoupled from the View and testable. All of this easily allowed us to solve a problem that at first look appears to be extremely difficult to implement when following the ViewModel design pattern. You’ll find nearly everything you run into that appears to be complicated to do when following the ViewModel pattern is actually easy to solve by using a service. In fact, you can find yourself going overboard here, and use services for problems that are better solved using other mechanisms. For instance, you could use a service to replace data bindings, but that wouldn’t be the correct solution to the problem. Don’t be too enticed by the power of services. Look first for alternative solutions, and if none present themselves, then look to the service as your solution. Remember the analogy from the last post, which is even more poignant this time around. You wouldn’t go duck hunting with a death star, nor should you solve most day to day problems with services. However, it’s nice to know there’s no problem you can’t solve as long as you’ve got services to back you up.

Read Full Post »

I’ve said online in a few different places that attached behaviors and services are your “big guns” when developing WPF applications that follow the ViewModel design pattern. If you run into something you’re finding difficult to program due to the nature of the ViewModel pattern, these are the concepts that will help get you out of the corner you’ve been painted into. I thought I’d write a little series of blog entries that elaborate on this.

The “Little Guns”

First, I’d better step back. I call the attached behavior and services “big guns” for a reason. They should not be your tool of choice on a daily basis. You wouldn’t go duck hunting with a bazooka, nor should you solve most day to day problems with behaviors or services. Most of the day to day problems are solved with the “little guns”, data bindings and commands. We’re only going to pull out the “big guns” when the problem is so large that the “little guns” wouldn’t put a dent in it.

Attached Properties

OK, today we’re just going to discuss attached behaviors. But in order to do so, we need to back up a little bit and discuss attached properties. I suppose, if I were really going to be thorough, I should back all the way up and discuss dependencies properties, but if you’re new enough to WPF to need me to go back that far, you’re not ready for this discussion ;).

An attached property is a dependency property that’s defined on one type, but that can be applied to a dependency object of another type. The typical example given when talking about attached properties are the Grid.Row and Grid.Column properties. These are defined by, and used by, the Grid type, but you set their values on children of the Grid that probably are different types that are entirely unaware of the Grid type and these properties.

    <Grid Margin="4">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0"/>
        <Button Grid.Row="1" Content="Test"/>
    </Grid>

The Remora Pattern

Early in the WPF lifetime, one BenCon blogged about a pattern that he called the Ramora (sic) pattern. I’m not sure if he’s the first to discover this pattern or not, but I’m going to give him credit, as folks are want to do on the intarweb thingy. Over time, this pattern came to be more commonly known as an “attached behavior”, and more recently with the Blend SDK we now just call it a Behavior (though a Behavior is a class that encapsulates this stuff, so don’t let that confuse you). Basically, and attached behavior is just an attached property that when set it applies some behavior to the item it’s attached to, usually by subscribing to some event on the item. If that’s clear as mud to you, hopefully things will become more clear as we actually implement a behavior.

This idea is important to the ViewModel design pattern because often what you’re wanting to do is enable the ViewModel to change the behavior of the View in some way.

Selection

We’re going to look at one of the more common problems you may face when following the ViewModel pattern that’s easily solved by using an attached behavior: tracking and changing the selection in a multi-select ListBox. For single-selection you have a couple of options. The CollectionView has a CurrentItem property that will be the selected item. However, it doesn’t expose a property that represents the selected items. On the ListBox itself the SelectedItem is a dependency property that you can bind to a property on your ViewModel. However, the SelectedItems is a read-only dependency property and can’t be used to track selection directly. The ListBox does have a SelectionChanged event that could be bound to the ViewModel, but that will only provide you with half a solution. You’re ViewModel could use this to track the selection made by the user, but could not use it to programmatically change the selection.

An attached behavior is a perfect solution to this problem. An attached property can be used to bind to a collection exposed by the ViewModel, and the remora pattern can then be used to monitor changes to either the ViewModel’s collection or the ListBox.SelectedItems collection, and apply those changes to the other collection.

public static class Selection
{
    private static readonly DependencyProperty SynchronizerProperty =
        DependencyProperty.RegisterAttached(
            "Synchronizer",
            typeof(ListSynchronizer),
            typeof(Selection));

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.RegisterAttached(
            "Items",
            typeof(IList),
            typeof(Selection),
            new PropertyMetadata(null, OnItemsChanged));

    public static IList GetItems(DependencyObject source)
    {
        return (IList)source.GetValue(ItemsProperty);
    }

    public static void SetItems(DependencyObject source, IList value)
    {
        source.SetValue(ItemsProperty, value);
    }

    private static void OnItemsChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        IList targetList = null;

        MultiSelector selector = source as MultiSelector;
        if (selector != null)
        {
            targetList = selector.SelectedItems;
        }
        else
        {
            ListBox listBox = source as ListBox;
            if (listBox != null)
            {
                targetList = listBox.SelectedItems;
            }
        }

        if (targetList == null)
        {
            return;
        }

        ListSynchronizer synchronizer = (ListSynchronizer)source.GetValue(SynchronizerProperty);
        if (synchronizer != null)
        {
            synchronizer.Dispose();
        }

        IList sourceList = (IList)e.NewValue;
        if (sourceList == null)
        {
            return;
        }

        synchronizer = new ListSynchronizer(sourceList, targetList);
    }
}

Internally here we’re using a ListSynchronizer type to encapsulate all of the event handling logic, and we’re storing an instance of this type in a private attached dependency property. Here’s the ListSynchronizer in all of its glory.

internal sealed class ListSynchronizer : IDisposable
{
    private bool disposed;
    private IList source;
    private IList target;

    public ListSynchronizer(IList source, IList target)
    {
        this.source = source;
        this.target = target;
        StartListening(this.source);
        StartListening(this.target);
        Synchronize();
    }

    ~ListSynchronizer()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void StartListening(IList list)
    {
        INotifyCollectionChanged incc = list as INotifyCollectionChanged;
        if (incc != null)
        {
            incc.CollectionChanged += OnCollectionChanged;
        }
    }

    private void StopListening(IList list)
    {
        INotifyCollectionChanged incc = list as INotifyCollectionChanged;
        if (incc != null)
        {
            incc.CollectionChanged -= OnCollectionChanged;
        }
    }

    private void Synchronize()
    {
        Synchronize(this.target, this.source);
        if (!this.target.Cast<object>().SequenceEqual(this.source.Cast<object>()))
        {
            Synchronize(this.source, this.target);
        }
    }

    private void Synchronize(IList source, IList target)
    {
        StopListening(target);
        try
        {
            foreach (object item in source)
            {
                target.Add(item);
            }
        }
        finally
        {
            StartListening(target);
        }
    }

    private void OnCollectionChanged(
        object sender,
        NotifyCollectionChangedEventArgs e)
    {
        IList targetList = object.ReferenceEquals(sender, this.source) ? this.target : this.source;
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                PerformActionOnList(targetList, e, Add);
                break;

            case NotifyCollectionChangedAction.Move:
                PerformActionOnList(targetList, e, MoveOrReplace);
                break;

            case NotifyCollectionChangedAction.Remove:
                PerformActionOnList(targetList, e, Remove);
                break;

            case NotifyCollectionChangedAction.Replace:
                PerformActionOnList(targetList, e, MoveOrReplace);
                break;

            case NotifyCollectionChangedAction.Reset:
                Synchronize();
                break;
        }
    }

    private void PerformActionOnList(
        IList list,
        NotifyCollectionChangedEventArgs e,
        Action<IList, NotifyCollectionChangedEventArgs> action)
    {
        StopListening(list);
        try
        {
            action(list, e);
        }
        finally
        {
            StartListening(list);
        }
    }

    private void Add(IList list, NotifyCollectionChangedEventArgs e)
    {
        int itemCount = e.NewItems.Count;
        for (int i = 0; i < itemCount; i++)
        {
            int insertionPoint = e.NewStartingIndex + i;
            if (insertionPoint > list.Count)
            {
                list.Add(e.NewItems[i]);
            }
            else
            {
                list.Insert(insertionPoint, e.NewItems[i]);
            }
        }
    }

    private void MoveOrReplace(IList list, NotifyCollectionChangedEventArgs e)
    {
        Remove(list, e);
        Add(list, e);
    }

    private void Remove(IList list, NotifyCollectionChangedEventArgs e)
    {
        int itemCount = e.OldItems.Count;
        for (int i = 0; i < itemCount; i++)
        {
            list.RemoveAt(e.OldStartingIndex);
        }
    }

    private void Dispose(bool disposing)
    {
        if (this.disposed)
        {
            return;
        }

        if (disposing)
        {
            StopListening(this.source);
            StopListening(this.target);
        }

        this.disposed = true;
    }
}

OK, that code is admittedly a tad complicated, but using it is not.

        <ListBox Grid.Row="0"
                 SelectionMode="Extended"
                 ItemsSource="{Binding Disciples}"
                 ui:Selection.Items="{Binding SelectedDisciples}"/>

I should note, similar behaviors have been posted before, including one by fellow Disciple Marlon Gretch. I chose to use this one anyway, because it does the best job of illustrating how a behavior can solve a common ViewModel problem. Besides, I think I was the first person to post such a solution to this problem, though finding it is difficult. I won’t point you there now, because this is a much better implementation and description.

I hope this helps someone new to WPF and the ViewModel pattern. Next up, services!

Edit: Ran across a blog post today by Edward Tanguay with another example, binding to a PasswordBox, where behaviors allow you to work around what would otherwise be a tricky area in the ViewModel pattern (I’ll note that another Disciple Peter O’Hanlon also blogged about a behavior for this, and I’ve had this one in my bag of tricks for quite a while).

Read Full Post »

SketchFlow Book

Unless you’ve been living under a rock, or you’re not a WPF/Silverlight developer I suppose, then you’ve heard about SketchFlow. We recently were given access to this exciting new tech in a recent Blend 3 release candidate (you’ll probably want the Silverlight 3 tools and developer runtime as well).

SketchFlow allows a designer to create prototypes that use actual WPF code that will be your starting point for the real application, but using a style that makes the PHB not assume the code is close to being ready to ship. This prototype also allows the PHB and other interested parties to annotate the live running application with feedback notes and “penciled” markings. This feedback can be exported and sent back to the designer, who can quickly make suggested changes. This is probably one of the most obvious, yet never implemented (to my knowledge) ideas to ever come down the pike. It’s sheer genius!

So, we get our first access to SketchFlow last week, and now there’s already public information about a book on the subject, including a free chapter download! Haven’t read this yet, but you know I’m going to.

Read Full Post »

Older Posts »