Faster Builds from Visual Studio


Just a quick note on something that helped me get my solutions builds to run faster as I develop.

First off, I’ll admit that “Faster Builds” is a bit of a stretch. I’m not actually making VS compile faster. Rather, I’m reducing the amount of time I waste waiting for a build to complete.

Time Consuming Builds…

Some solutions have a ton of stuff going on in their compilation process:

  • Numerous projects (presentation, business, data, etc)
  • Unit tests (maybe one per project)
  • Static code analysis
  • NDepend
  • Etc.

It’s relevant to point out that solutions have a certain order that they build their projects. This is automatically determined based on the inter-project references. Projects that are a dependency of many other projects must be built first. Making a change to one of these “root” projects means that everything else must be rebuilt too.

In some of these cases, building the entire solution can take some time, especially when the changes are in one of the “root” projects that is built first. I found this a bit annoying, especially when it returns with an error. But what to do? I don’t want to turn off the safety nets that the static code analysis or NDepend offers. I don’t want to unload projects or remove them from the solution.

Building Selected Projects

The thing that seems to be working well for me so far is to build individual projects. If there is an error in the DTO project’s classes, then I only have to build one or two projects to find out, rather then building the whole solution. This saves a fair bit of time because I can get the DTO project working and then move on to other projects.

Setting up the Shortcut Key

You can build a specific project by right clicking on it, or by selecting it and then using the file menu. But, again, even that is kind of annoying. I’m a fan of “CTL+SHIFT+B” to build solutions. The problem is that VS doesn’t seem to have a built in shortcut key for “Build Selected Project”. Luckily, you can change this by editing the VS options:

VS2010 Keyboard Options

By default, the “Build.BuildSelection” command has no shortcut key. I tried a couple options and settled on “ALT+B”. This didn’t appear to be in use and was relatively comfortable for me to access.

Cheers!

author: Nathan Allen-Wagner | posted @ Tuesday, June 15, 2010 12:00 AM | Feedback (6)

Be careful about with e.Handled in mouse or keyboard events


Today, I finally resolved an issue that I thought was related to WPF’s focus implementation. For some reason, I couldn’t get certain elements to get focus when I clicked on them. This was messing up a number of other things, including keyboard interactions and routed commands. I thought that I had some strange scenario that was preventing focus from going to my canvas. Maybe some issue with FocusScopes? Maybe the control wasn’t Focusable?

It turns out that I had a number of event handlers set up for clicking, dragging, etc. In these, I was setting e.handled = true. Not good!

There are cases where you’ll want to set e.handled to true, but be careful. In my case, this prevented a mouse click from moving focus to the control.

Cheers!

author: Nathan Allen-Wagner | posted @ Thursday, June 10, 2010 3:54 PM | Feedback (0)

WPF Routed Commands + MVVM


A lot of the MVVM guidance around commands suggest using a generic ICommand implementation, such as the RelayCommand or GenericCommand implementations. These are great for UI pieces that are bound directly to an underlying ViewModel and I use them frequently.

There are still cases where a RoutedUICommand is exactly what one needs. Take, for instance, toolbar buttons or menu items that need to act on pages that are loaded in a WPF frame. In this case, a RoutedUICommand is appropriate since it is decoupled from the page, which may or may not be loaded at the time.

One challenge with MVVM based scenarios is connecting a routed command to an implementation that lives in the ViewModel. As usual, Josh Smith has an solution… Josh wrote a ViewModel Commanding sample back in 2008 and posted it to CodeProject.

It took me a little bit of review to understand the way it works, but the end result is a very clean and simple implementation that stays close to the original design intent behind WPF’s routed commands.

Thanks Josh!

author: Nathan Allen-Wagner | posted @ Thursday, June 10, 2010 3:44 PM | Feedback (0)

Stuff hitting my “Radar”


I recently started listening to the Herding Code podcast and BoagWorld podcast and have subsequently been exposed to some really interesting “stuff”. I thought I’d put these down, if for no other reason than helping me remember to try them out.

JSConf

Javascript is getting a lot of attention and investment lately. This is both in the browser and on the server. There are a ton of cool things going on, many of which are discussed at JSConf.

One of the trippy things I heard about is a JS library that will rip flash into HTML5 on the client, eliminating the need for the plug-in.

The other thing they talked about was the security aspects around the web in general. All I can say is “unplug your internet connection now!” Also good justifications for having separate passwords (and usernames?) for each site.

Fluent Validation

The Fluent Validation library makes validation (and some business rules) almost a pleasure to write. I’ve used this with good results. Highly recommended!

Web Protection Library

I’ve heard of the Anti-XSS library, but I recently learned that MS released the successor to this in the form of the Web Protection Library. The implementation is a bit different and the feature set is a bit wider than it’s predecessor.

RestSharp and Hammock

All the “cool kids” are doing REST. Those living in Microsoft land have some support for this via WCF, OData, etc. But it can still be a little tricky.

RestSharp and Hammock for REST are two open source projects that make it really simple to consume REST based services. I’ve tried both and ended up using Hammock. Very nice work by both projects!

Twilio

This is not a library. It’s a service. It took me a minute to get the vision, but I think it’s really cool…

Twilio is a REST API for “voice-enabling” your app and/or sending SMS messages. The voice part is cool because you can build a speech enabled “IVR” really easily.

NoSQL DBs

This is another thing that all the cool kids are doing… DBs without SQL. No, this is not the resurrection of Object Databases. Rather, this is the movement to “Document Databases”.

A Document Database is one that stores a chunk of data as a single unit. In some ways, it’s kind of like storing a chunk of XML in a SQL Server XML column.

The difference is that document databases often store the data using a JSON (or BSON) type format. They support many of the standard DB-ish features like indexes, queries, inserts, updates, LINQ, transactions, replication, backups, etc. They also enable some new features that are not simple in a relational model, like crazy fast performance, sharding, etc.

I sort of wish that I would have known and considered these for a couple projects as they would have made certain scenarios much simpler and decreased the development time significantly.

So far, I’ve looked into (but not yet used):

MongoDB is a fairly mature, open source, C++ based, cross platform, cross language implementation. It also has a commercial option.

RavenDB is an open source and/or commercial implementation that is tailored a bit more toward .NET. My investigation indicated that it has some features that management might like to see, such as ACID transaction, integration with .NET TransactionScopes, online backups, etc.

Michael C. Kennedy has a great series of posts on NoSQL.

MVC Turbine

I’d heard of MVC Turbine a while back, but recently heard the interview on Herding Code, which helped me understand what it does and why it is.

From what I understand, the key feature is it’s “glue” that lets you use an IoC container with MVC. Apparently, this is not simple to do on your own. With this in place, the framework can add some really nice features to an MVC app.

Fluent Migrator

Just heard about Fluent Migrator one today. I’m intrigued by the concept of writing database migration steps in .NET such that they are DB agnostic and allow for easily moving a DB from one version to the next. This can be used in automated testing, automated deployments, and just getting a DB setup in the first place.

I’m still a big fan of the VS DB projects and Red-Gate’s tools, but this seems like another nice tool to have in one’s toolbox.

Reactive Extensions

RX for .NET and RX for JavaScript are two implementations of a pattern that make it simpler to “subscribe to events” and then do interesting filters or aggregations over multiple events and how those events relate to each other. There is a ton of info out there on these. Definitely worth a look. I hope to explore the applicability of these in a WPF app soon.

Clipperz

Clipperzis a “Web Rolodex for your passwords”. The cool thing is that they use client side, JavaScript based encryption technologies. They also follow a “Zero-Knowledge” approach and use the SRP protocol, meaning that the company itself has no way to decrypt the data that you store on their servers. Heady stuff, but very cool.

 

Cheers!

author: Nathan Allen-Wagner | posted @ Thursday, June 10, 2010 10:18 AM | Feedback (0)

WPF Style and Template Resources – Order Matters


When working with WPF resources, remember to declare the resources in the correct order.

A style or template that is referenced elsewhere must be defined before it can be used. In other words, if Style1 uses BrushA as a StaticResource, then BrushA must be defined before Style1. Otherwise, you’ll get fun errors like:

Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.Windows.FrameworkTemplate'

It may be common knowledge, but it can be a real pain to diagnose. This is especially true if you have a large set of template and styles for an application. It gets even more fun when you have multiple themes.

Cheers.

author: Nathan Allen-Wagner | posted @ Friday, May 07, 2010 4:44 PM | Feedback (1)

MVVM ViewModel Locator via WPF Converters


Laurent Bugnion’s work on MVVM Light introduced me to the ViewModel Locator pattern. The concept and implementation are really slick!

From my perspective, ViewModel Locators do the following:

  1. Provide a simple, declarative way to connect a View to a ViewModel (duh).
  2. Enable design-time support, including the ability to connect an alternate data source behind the VM (cool!).

I want a solution that lets me:

  1. Connect my XAML views to their associated ViewModels
  2. Handle a somewhat complex model with a hierarchy of domain model entities and collections.
  3. Support “state” in the ViewModel and remember that state during the lifetime of the application.

After installing and attempting to use the MVVM Light implementation, I found that it wasn’t quite working the way I needed. After fumbling around a bit, doing some research, I stumbled on the idea of using a WPF converter (IValueConverter).

I’ve put together a sample application which demonstrates this pattern and shows some of the scenarios that would otherwise be difficult to achieve.

Here is a link to the source code for the demo:

Demo Application – MVVM ViewModel Locators via IValueConverter Converters

Here you can see the initial state of the application. It has some inline text and a walkthrough scenario so that you can see the behavior of the app.

image

Here you can see the app after walking though the usage steps. The inline text also highlights a couple key points to notice from the behavior.

image

Enough Chit-Chat. Code Please!

Let’s step back for just a moment and set some context. Laurent Bugnion’s VM Locators are design such that you create a special class in your application that can generate ViewModels as needed. This class is included as a resource in the app.xaml…

<vm:ViewModelLocatorTemplate 
   xmlns:vm="clr-namespace:ProjectForTemplate.ViewModel" 
   x:Key="Locator" 
/>        

… and then used in your code like this…

<DockPanel 
    DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
    LastChildFill="True"
>

 

The class itself has properties for each of the ViewModels that you need to use in your application. The logic behind these includes some great features that create sample data for design time support.

However…

… I ran into some issues when I tried to use this with a domain model that included a hierarchy of inter-related objects and collections of objects. I was unable to see how I could use a single class, with static properties to return multiple instances of a single type of ViewModel.

I considered an approach that would pre-construct a hierarchy of ViewModels that matched the hierarchy of the domain model. Then I could simply pass that into my views and bind accordingly. However, at the suggestion of Richard Broida, I took the alternate approach of creating the ViewModels separately, on demand, and caching them. The end result feels right to me.

The XAML

Here is my code from my MainWindow of the sample app. As you can see, I have a hierarchy of domain model objects where a parent object might have multiple children in a collection.

<Window x:Class="ViewModelLocatorsWithConverters.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Converter ViewModel Locator Demo" 
        Height="600" Width="800" 
>

    <!-- DataContext: MainViewModel -->
    <DockPanel 
        DataContext="{Binding Converter={StaticResource MainVMLocator}}"
        LastChildFill="True"
    >
        <ScrollViewer VerticalScrollBarVisibility="Auto" DockPanel.Dock="Right">
             ...
        </ScrollViewer>
        <StackPanel DockPanel.Dock="Top">
            <DockPanel HorizontalAlignment="Stretch">

                <Label Margin="0" VerticalContentAlignment="Bottom" 
                       VerticalAlignment="Bottom" 
                       FontSize="16" 
                       FontWeight="Bold"
                       DockPanel.Dock="Left"
                >Families:</Label>


                <Button Command="{Binding LoadFamiliesCommand}" 
                        HorizontalAlignment="Right" 
                        Margin="5" MinWidth="100"
                        DockPanel.Dock="Right"
                >Load Families</Button>

                <Label Margin="0" VerticalContentAlignment="Bottom" HorizontalAlignment="Right"
                       VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold" Foreground="Green"
                       DockPanel.Dock="Right"
                >Start Here -&gt;</Label>

            </DockPanel>
            <ComboBox 
                ItemsSource="{Binding Families}" 
                DisplayMemberPath="FamilyName" 
                IsSynchronizedWithCurrentItem="True"
                SelectedItem="{Binding CurrentFamily}" Margin="5">
            </ComboBox>
        </StackPanel>

        <!-- DataContext: FamilyViewModel -->
        <DockPanel 
            DataContext="{Binding CurrentFamily, Converter={StaticResource FamilyVMLocator}}" 
            Margin="0,10,0,0">

            <DockPanel DockPanel.Dock="Top" Margin="0">
                <Label VerticalAlignment="Bottom" VerticalContentAlignment="Bottom" 
                       FontSize="16" FontWeight="Bold">Family Members:</Label>
                <Button 
                    Command="{Binding TogglePetsCommand}" 
                    HorizontalAlignment="Right"
                    Content="{Binding ShowPetsButtonText}" Margin="5" MinWidth="100" />
            </DockPanel>

            <ListBox HorizontalContentAlignment="Stretch"
                ItemsSource="{Binding Family.Members}" 
                SelectedItem="{Binding SelectedPerson}" Margin="5">
                <ListBox.ItemTemplate>
                    <DataTemplate>

                        <!-- DataContext: PersonViewModel -->
                        <Grid 
                            HorizontalAlignment="Stretch"
                            DataContext="{Binding Converter={StaticResource PersonVMLocator}}" 
                        >
                            <Border BorderThickness="2" BorderBrush="Green" 
                                    CornerRadius="4" HorizontalAlignment="Stretch">
                                <TextBlock Margin="10, 2" MinWidth="200" FontFamily="Verdana">
                                    <TextBlock Text="{Binding FormattedName}" FontWeight="Bold" />
                                    <LineBreak/>
                                    <TextBlock Text="  (" />
                                    <TextBlock Text="{Binding Person.Role}" />
                                    <TextBlock Text=")" />
                                </TextBlock>
                            </Border>
                        </Grid>

                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </DockPanel>

    </DockPanel>
</Window>

 

I’ve highlighted the bindings to help pull out the data that is rendered and the interaction with the ViewModel.

Notice the three uses of a “Locator” such as:

DataContext ="{ Binding Converter ={ StaticResource MainVMLocator }}"

These are references to the “Converter-Based ViewModel Locators”. They are pulled into that application via declarations in the app.xaml file as follows:

<Application x:Class="ViewModelLocatorsWithConverters.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:l="clr-namespace:ViewModelLocatorsWithConverters.Locators"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

        <!-- 
        ********************************************************* 
        Declare VM Locators here for use throughout the application. 
        *********************************************************  
        -->
        <l:FamilyViewModelLocator x:Key="FamilyVMLocator" />
        <l:MainViewModelLocator x:Key="MainVMLocator" />
        <l:PersonViewModelLocator x:Key="PersonVMLocator" />
        
    </Application.Resources>
</Application>

 

 

 

There is one locator created for each ViewModel in the application.

Converter-Based Locators

So what does this converter based locator look like? The following class is one of three in the sample application. It’s job is to do the best it can to get a reference to the DomainModel using whatever was passed in as a parameter to the converter. Once it has a reference to the DomainModel instance, it can see if it already has a cached ViewModel, or it can create a new instance of the ViewModel.

using System;
using System.Windows.Data;
using ViewModelLocatorsWithConverters.Model;
using ViewModelLocatorsWithConverters.ViewModels;
using System.Globalization;

namespace ViewModelLocatorsWithConverters.Locators
{
    /// <summary>
    /// Provides a method and a XAML IValueConverter to get the viewmodel 
    /// that is associated with the specified model or view model.
    /// </summary>
    public class PersonViewModelLocator : IValueConverter
    {

        /// <summary>
        /// For the specified parameter, find or create an appropriate viewmodel.
        /// </summary>
        /// <param name="value">An instance of a "parent" view model, 
        /// or an instance of the domain model class.</param>
        /// <returns>A new, or previously used view model instance.</returns>
        public static PersonViewModel GetPersonViewModel(object value)
        {
            // Check if we already have an instance of the viewmodel
            var vm = value as PersonViewModel;

            if (null == vm)
            {
                // The instance of the model that the ViewModel will handle.
                Person model = null;

                // See if the specified parameter is a known type.
                var Person = value as Person;

                // Pull the desired domain model class from the parameter.
                if (ViewModelLocator.IsInDesignMode)
                    model = ViewModelLocator.InitDesignTimeInstance().Members[0];
                else if (null != Person)
                    model = Person;
                else
                    throw new ArgumentException("Value parameter must be an instance of a " + 
                        "Person or PersonViewModel. Specified value is of type " + 
                        (null == value ? "<null>" : value.GetType().AssemblyQualifiedName), 
                        "value");

                // Get or create the ViewModel
                vm = ViewModelLocator.GetViewModel<PersonViewModel>(model);
                if (null == vm)
                {
                    vm = new PersonViewModel(model);

                    // Save the VM in the cache. It will be used again if the same Person is shown again.
                    ViewModelLocator.CacheViewModel(model, vm);
                }
            }

            return vm;
        }


        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return GetPersonViewModel(value);
        }

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

 

The ViewModel Cache

A single ViewModelLocator helper class stores the cache of ViewModels. This cache is keyed by the DomainModel instance. Here is the relevant code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using ViewModelLocatorsWithConverters.Model;
using ViewModelLocatorsWithConverters.ViewModels;

namespace ViewModelLocatorsWithConverters.Locators
{

    /// <summary>
    /// Stores a cache of view model instances. Also detects design time mode.
    /// </summary>
    /// <remarks>
    /// This is an internal class for use by the ViewModelLocator classes.
    /// Portions of this implementation are based on work by Laurent Bugnion (Galasoft).
    /// </remarks>
    public static class ViewModelLocator
    {

        #region Member Variables

        // Store a list of ViewModel instances, keyed by their associated model instance.
        // Key is a composite of the related instance plus the type of viewmodel. 
        // This is because a given instance could have multiple views.
        private static Dictionary<Tuple<object, Type>, ViewModelBase> _ViewModelCache 
            = new Dictionary<Tuple<object, Type>, ViewModelBase>();

        // Flag indicating whether the view is loaded in the designer.
        // Access via the property getter.
        private static bool? _isInDesignMode;

        #endregion

        #region Constructors

        #endregion

        #region Public Methods


        /// <summary>
        /// Gets a value indicating whether the control is in design mode
        /// (running in Blend or Visual Studio).
        /// </summary>
        public static bool IsInDesignMode
        {
            get
            {
                if (!_isInDesignMode.HasValue)
                {
#if SILVERLIGHT
                    _isInDesignMode = DesignerProperties.IsInDesignTool;
#else
                    var prop = DesignerProperties.IsInDesignModeProperty;
                    _isInDesignMode
                        = (bool)DependencyPropertyDescriptor
                        .FromProperty(prop, typeof(FrameworkElement))
                        .Metadata.DefaultValue;

                    // Just to be sure
                    if (!_isInDesignMode.Value
                        && Process.GetCurrentProcess().ProcessName.StartsWith("devenv", StringComparison.Ordinal))
                    {
                        _isInDesignMode = true;
                    }
#endif
                }

                return _isInDesignMode.Value;
            }
        }


        #endregion

        #region Internal Methods

        /// <summary>
        /// Get a previously cached ViewModel from the cache.
        /// </summary>
        /// <typeparam name="T">The type of the ViewModel instance.</typeparam>
        /// <param name="model">
        /// A reference to the instance of the model that is related to this ViewModel instance.
        /// This can be null if there is no model, as is often the case for the "main" or "root" ViewModel.
        /// </param>
        /// <returns>The cached ViewModel, or null if none is found.</returns>
        internal static T GetViewModel<T>(object model) where T : ViewModelBase
        {
            var key = new Tuple<object, Type>(model, typeof(T));
            if (_ViewModelCache.ContainsKey(key))
                return _ViewModelCache[key] as T;
            else
                return null;
        }

        /// <summary>
        /// Cache a ViewModel so that it can be used again if/when the domain model is
        /// displayed again.
        /// </summary>
        /// <param name="model">
        /// A reference to the instance of the model that is related to this ViewModel instance.
        /// This can be null if there is no model, as is often the case for the "main" or "root" ViewModel.
        /// </param>
        /// <param name="viewModel">
        /// The instance of the ViewModel to cache.
        /// </param>
        internal static void CacheViewModel(object model, ViewModelBase viewModel)
        {
            var key = new Tuple<object, Type>(model, viewModel.GetType());
            _ViewModelCache.Add(key, viewModel);
        }

        /// <summary>
        /// Remove a ViewModel from the cache.
        /// </summary>
        /// <typeparam name="T">The type of the ViewModel to clear.</typeparam>
        /// <param name="model">The instance of the model that this ViewModel was linked to. This can be null.</param>
        internal static void ClearViewModel<T>(object model) where T : ViewModelBase
        {
            var key = new Tuple<object, Type>(model, typeof(T));
            ViewModelBase vm = null;

            if (_ViewModelCache.ContainsKey(key))
                vm = _ViewModelCache[key];

            if (vm != null)
            {
                _ViewModelCache.Remove(key);
            }
        }

        #endregion

        #region Designer Data Helpers

        /// <summary>
        /// Create some instances of the domain model for use during design time.
        /// </summary>
        /// <returns></returns>
        internal static Family InitDesignTimeInstance()
        {
            Family family = new Family() { 
                FamilyName = "Design Time Family" 
            };

            family.Members.Add(new Person()
            {
                Name = "John Doe",
                Role = "Father"
            });

            family.Members.Add(new Person()
            {
                Name = "Jane Doe",
                Role = "Mother"
            });

            family.Members.Add(new Person()
            {
                Name = "Jimmy Doe",
                Role = "Child"
            });

            family.Members.Add(new Person()
            {
                Name = "Jill Doe",
                Role = "Child"
            });

            family.Members.Add(new Person()
            {
                Name = "Spot",
                Role = "Dog"
            });
            
            return family;
        }

        #endregion

    }
}

This class is based on the work of Laurent Bugnion in his MVVM Light implantation. I’ve added supporting methods for caching and retrieving ViewModel instances.

Benefits and Shortcomings

The above approach really shines in a couple scenarios:

Bound collections

If you have a collection of domain model objects that you want to bind into the view, you could simply bind that collection directly. That works for simple cases.

What if you have a need to do some formatting, add some commands, do some additional lookups, etc? That’s what ViewModels are for, right? But how do I inject a ViewModel between the collection and the ItemsControl / ListBox / etc.? You could do something like I’ve mentioned in a previous post using Bindable Linq, Continuous Linq, Obtics, or even the new Linq library from ComponentOne. That has it’s benefits, but might not be an option.

The MVVM Light locator doesn’t seem to help here because I only get a single instance of the ViewModel from the Locator, and it isn’t “hooked up” to the instance of the domain model that’s in my collection.

So…

Using a converter, I can “inject” a ViewModel during the binding operation such that the items in my ItemsControl / ListBox / whatever are now bound to an instance of a ViewModel.

On top of that, the ViewModel is “married” to the instance of the domain model so that I can have item-specific view related state. This state might include things like filter options, positions, sizes, item visibility, etc. This information might not have a durable storage location, but it’s not something that should be lost just because I went to another tab / page / item / view in my application.

Composable UIs

There are some cases, where you might create a user control that is shown from many locations in the application. This user control needs to get a reference to the ViewModel on which it depends. How does one do this?

You could set the DataContext in each location that you use the control, but…

A Converter-based locator provides some nice benefits in that the user control can figure it out for itself. The locator takes in the “ambient DataContext” based on where it is hosted in the UI. This ambient context could be another ViewModel, another DomainModel, the actual ViewModel used by the control, or the actual DomainModel used by the control.

In any of the above cases, the locator simply inspects the instance passed to the converter and reacts accordingly. In the case of a “parent” ViewModel, the converter might be able to use a property on that ViewModel to get a reference to the instance needed by the UserControl.

Design-Time Support

As with MVVM Light, the above implementation enables design-time support, making the solution “Blend-able”. You can see in the screen shot below that the drop down has some design time data in it. You can also see that the ListBox has items in it based on the data that I created in my ViewModelLocator when it detected design time.

Design time support in VS 2010

Shortcomings

There are some known issues in the current version. The main item is the fact that the cache holds a strong reference to the ViewModel and the DomainModel objects. This can be overcome with the use of WeakReferences and the WeakEventManager. I hope to address this soon.

Related to this is the question of “closing” or cleaning up an instance. This is something that I also hope to address soon. I haven’t had a strong need to dispose of ViewModels or DomainModels yet, but I know that it is an important scenario.

Call to Action

Please let me know what you think.

Maybe I missed some simple concept with MVVM Light that would make all of this unnecessary. Maybe there are other implementations that do this pattern already. Maybe you see a major flaw in the approach.

… Or maybe this is useful.

I’m hoping for useful ;-]

Cheers!

 

P.S. In case you missed it, the link to the source code for the demo is included at the top of this post.

author: Nathan Allen-Wagner | posted @ Thursday, May 06, 2010 12:05 AM | Feedback (0)

Cancelling Selection Change in a Bound WPF Combo Box


Scenario

A user selects a new value from a WPF combo box. You ask if they are sure they want to do this. User says “No”.

WPF app is built with MVVM such that the combo box’s SelectedItem is bound to a property on the ViewModel. In the setter, you prompt the user and attempt to cancel the selection by discarding the new selected value.

Here’s the UI XAML

<Window x:Class="WpfComboBoxCancelSelect.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Cancellable Combo Box Demo" Height="158" Width="242"
>
    <Grid>
        <StackPanel>
            <Label>Normal - This doesn't work</Label>
            <ComboBox 
                HorizontalAlignment="Left" 
                VerticalAlignment="Top"
                ItemsSource="{Binding People}"
                SelectedItem="{Binding CurrentPerson, Mode=TwoWay}"
                DisplayMemberPath="Name"
            />
            <Label>Cancellable Combo - This works.</Label>
            <ComboBox 
                HorizontalAlignment="Left" 
                Name="comboBox2" 
                VerticalAlignment="Top"
                ItemsSource="{Binding People}"
                SelectedItem="{Binding CurrentPersonCancellable, Mode=TwoWay}"
                DisplayMemberPath="Name"
            />
        </StackPanel>
    </Grid>
</Window>

 

Here are screen shots of my sample UI

image

image 

Attempt #1 - The way you’d think it would work

You’d think that you could do something like this:

 

private Person _CurrentPerson;
public Person CurrentPerson
{
    get
    {
        Debug.WriteLine("Getting CurrentPerson.");
        return _CurrentPerson;
    }
    set
    {
        if (value == _CurrentPerson)
            return;

        if (
            MessageBox.Show(
                "Allow change of selected item?", 
                "Continue", 
                MessageBoxButton.YesNo
            ) != MessageBoxResult.Yes
        )
        {
            Debug.WriteLine("Selection Cancelled.");

            // You would think this should work, but it doesn't.
            // This is called within the same binding "context" 
            //  as that of the original setter.
            // The value needs to be changed back in a subsequent setter.
            OnPropertyChanged("CurrentPerson");
            return;
        }

        Debug.WriteLine("Selection applied.");
        _CurrentPerson = value;
        OnPropertyChanged("CurrentPerson");
    }
}

 

This doesn’t work. The ViewModel will have the values that you desire, but the UI will look like it applied the changes.

Attempt #2 – BeginInvoke() the PropertyChanged event

Based on info from this Stack Overflow question, I tried the following. This still didn’t work for me. (Note that I’m working with WPF 4.0 RTM).

private Person _CurrentPersonTry2;
public Person CurrentPersonTry2
{
    get
    {
        Debug.WriteLine("Getting CurrentPersonTry2.");
        return _CurrentPersonTry2;
    }
    set
    {
        if (value == _CurrentPersonTry2)
            return;

        if (
            MessageBox.Show(
                "Allow change of selected item?",
                "Continue",
                MessageBoxButton.YesNo
            ) != MessageBoxResult.Yes
        )
        {
            Debug.WriteLine("Selection Cancelled.");

            // Tell the UI that it should re-bind the value.
            // Do this after the UI has finished it's 
            // current context operation.
            Application.Current.Dispatcher.BeginInvoke(
                    new Action(() =>
                    {
                        Debug.WriteLine(
                            "Dispatcher BeginInvoke " +
                            "Setting CurrentPersonTry2."
                        );

                        OnPropertyChanged("CurrentPersonTry2");
                    }),
                    DispatcherPriority.ContextIdle,
                    null
                );

            return;
        }

        Debug.WriteLine("Selection applied.");
        _CurrentPersonTry2 = value;
        OnPropertyChanged("CurrentPersonTry2");
    }
}

The above code works just like the first version.

Attempt #3 – The final solution

On a whim, I figured I’d try another tweak. I tried letting the underlying value appear to change so that I could change it back to the original value on a BeginInvoke operation. For whatever reason, this does work.

private Person _CurrentPersonCancellable;
public Person CurrentPersonCancellable
{
    get
    {
        Debug.WriteLine("Getting CurrentPersonCancellable.");
        return _CurrentPersonCancellable;
    }
    set
    {
        // Store the current value so that we can 
        // change it back if needed.
        var origValue = _CurrentPersonCancellable;

        // If the value hasn't changed, don't do anything.
        if (value == _CurrentPersonCancellable)
            return;

        // Note that we actually change the value for now.
        // This is necessary because WPF seems to query the 
        //  value after the change. The combo box
        // likes to know that the value did change.
        _CurrentPersonCancellable = value;

        if (
            MessageBox.Show(
                "Allow change of selected item?", 
                "Continue", 
                MessageBoxButton.YesNo
            ) != MessageBoxResult.Yes
        )
        {
            Debug.WriteLine("Selection Cancelled.");

            // change the value back, but do so after the 
            // UI has finished it's current context operation.
            Application.Current.Dispatcher.BeginInvoke(
                    new Action(() =>
                    {
                        Debug.WriteLine(
                            "Dispatcher BeginInvoke " + 
                            "Setting CurrentPersonCancellable."
                        );

                        // Do this against the underlying value so 
                        //  that we don't invoke the cancellation question again.
                        _CurrentPersonCancellable = origValue;
                        OnPropertyChanged("CurrentPersonCancellable");
                    }),
                    DispatcherPriority.ContextIdle,
                    null
                );

            // Exit early. 
            return;
        }

        // Normal path. Selection applied. 
        // Raise PropertyChanged on the field.
        Debug.WriteLine("Selection applied.");
        OnPropertyChanged("CurrentPersonCancellable");
    }
}

 

The important change was to Actually change the underlying value and then change it back. It was also important to run this “undo” on a separate dispatcher operation.

Closing Thoughts

I’ve attached the sample solution if you want to see this in action.

 

I’m not sure what I think about this overall. It sort of makes sense once you get it working, but this is definitely not intuitive. I would think that simply raising PropertyChanged would tell WPF that to re-query the value. It should detect this and undo the change in the combo box. Doing this on a separate Dispatcher operation is tolerable, but having to make it look like the value actually took and then undoing it seems like it crosses the line of sanity.

Hopefully someone can show me a better way. For now, this works.

Cheers!

author: Nathan Allen-Wagner | posted @ Sunday, April 25, 2010 4:38 PM | Feedback (3)

I <3 LinqKit – Dynamically build arbitrarily complex Linq Queries


In some cases, I need to be able to build a query that has a variable set of OR conditions. This is not simple with the default language constructs and extension methods.

It’s simple to dynamically build an expression that includes AND parameters, because that is what the WHERE() extension method does. Not so easy for OR’ing together a bunch of conditions.

Enter LinqKit.

This is a great library. It provides some easy to use (but powerful) extension methods that let you “Or()” some conditions together. A common case is where you get a list of values that you need to add into the condition. You iterate over these and append them to an expression in a foreach() loop. Check out the LinqKit page for some great samples and explanations. I’d share some of my stuff, but their page is already awesome.

Cheers!

author: Nathan Allen-Wagner | posted @ Wednesday, April 14, 2010 11:42 AM | Feedback (0)

Entity Framework 4.0 doesn’t enforce MaxLength metadata


I’m a little flabbergasted that Entity Framework does not do anything to enforce the MaxLength on string values. It just passes this responsibility down to the database and catches the resulting (unhelpful) exceptions.

I suppose that there is a justification for this, but from an notably simplistic perspective… Why should I start a transaction and waste precious DB resources, only to get some generic “String or binary data may be truncated” error message back. It would be trivial for EF to use the metadata to ensure that you cannot push a 10 character string into a field that only holds 5.

I’ll grant you that I may want to allow the domain model to store this data temporarily, since it is an acceptable use case to allow a domain model to be in an invalid state during some part of it’s “in-memory” life-cycle. But databases don’t follow this same forgiving behavior. They’re stubborn and just refuse the data with a vague message.

It seems like EF should have a check that it does on the data, prior to committing it, that returns a helpful exception message if some of the data violates the EF model’s constraints. It could even go so far as to tell you which field on which object has a disreputable value.

I know that I can implement this by altering the T4 templates, and this is a huge improvement over past options (I love T4!). But I was surprised to see that EF didn’t provide this out of the box. Not for Self Tracking entities. Not for “standard” entities.

I’ve told Richard Broida that EF is my friend. It’s still my friend. I just want my friend to be more helpful. I guess I’ll pick up the slack for now.

Cheers!

author: Nathan Allen-Wagner | posted @ Tuesday, April 13, 2010 3:42 PM | Feedback (3)

VS 2010 Premium RTM – Got It!


After a couple hiccups with the download yesterday, I finally got the bits and got VS 2010 Premium installed. Great stuff! I’m glad to be running this on the host again, rather than a VM. I can take advantage of multi-monitor, GPU acceleration, and better speed! Hotness!

My current project is using TFS Power Tools for the check-in policies. My searching indicates that RTM versions are not available yet. So, I’m hoping that the TFS Power Tools RC bits will do for now. As far as I can tell, it’s working so far. My work item policy, comments, and up-to-date-build policies are all nagging me appropriately.

Upward and onward!

Cheers.

author: Nathan Allen-Wagner | posted @ Tuesday, April 13, 2010 8:04 AM | Feedback (0)