MEF Talk at LCNUG

by Administrator 23. July 2010 02:02

Next week Thursday in Grayslake, Illinois I’ll be speaking on one of my favorite new topics, in this case MEF !

You can find directions and register here:

http://www.lcnug.org/Home.aspx

I have a great deal of both entry-level and advanced MEF content and how much we get through will depend upon the attendees.  I’ll be using mostly Silverlight and WPF to demonstrate different bits of MEF-Fu though there may be some surprises too…

Tags:

I’m Back

by Administrator 19. July 2010 04:21

I was out of the country last week.  I managed to not touch a computer or Smartphone of any kind for eight full days.  I even made my wife use the check-in kiosks in the airport.

To everyone who contacted me as part of their recruiting efforts, or were seeking to learn the identities of the MSDN subscription winners, or had technical presentation related questions, I apologize.  I don’t advertise the fact that I won’t be home on the same blog where you can find pictures of my toys ;).

This is only the second time my wife and I have been able to get out together for a no-kids vacation. 

DamonChitzenItza

Tags:

Great Features for MVVM Friendly Objects Part 2 – Change/Dirty Tracking

by Administrator 6. July 2010 01:33

It’s often very useful to know when an object we are editing has Changed.  The most iconic example is the “*” that used to appear next to the title of Word documents once you’d made the first change no matter how small.  It’s not an unusual request that a “Save” button be disabled until the User has made a savable change.  This is often referred to as an object being Dirty.

This article is part of a series about useful MVVM friendly features for your data objects and favoring composition over inheritance.  You can read the other parts:

Dirty Aware

Now that we’ve introduced the idea of Property Change Behaviors, it’s easy for us to flag an object as having changed when we set any property value.  Let’s refer back to the BBGrill object in the Metro BBQ sample application.  I find it’s useful to standardize the HasChanges/Dirty state using an interface. 

/// <summary>
/// Capable of storing and notifying Dirty/HasChanged state
/// </summary>
public interface IDirtyAware
{
    bool IsDirty { get; set; }
    bool SuspendChangeNotification { get; set; }
}

We can now author a new IPropertyChangedBehavior that deals with IDirtyAware instances and sets their IsDirty flag to true whenever a property value changes.

public class DirtyPropertyBehavior : IPropertyChangedBehavior
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="owningInstance"></param>
    public DirtyPropertyBehavior(IDirtyAware owningInstance)
        : this(owningInstance, new List<string>() {"IsDirty"})
    {

    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="owningInstance"></param>
    /// <param name="exclusions"></param>
    public DirtyPropertyBehavior(IDirtyAware owningInstance, List<string> exclusions)
    {
        _owner = owningInstance;
        _propertyExclusions = exclusions;
    }

    IDirtyAware _owner;
    List<string> _propertyExclusions;

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="owningInstance"></param>
    /// <param name="oldVal"></param>
    /// <param name="newVal"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public bool PropertyChanged<T>(object owningInstance, T oldVal, T newVal, string propertyName)
    {
        if (!Object.Equals(oldVal, newVal) 
            && !_propertyExclusions.Contains(propertyName)
            && !_owner.SuspendChangeNotification)
        {
            _owner.IsDirty = true;
        }
        return true;
    }
}

Note that we can easily provide the ability to exclude certain properties from setting IsDirty, which is very useful for the IsDirty property itself.

Obviously we could put this functionality right inside the property setters but we want to make it easy to add/remove behaviors to objects.

Dirty Grill

Going back to the Metro BBQ sample application, I can now make BBQGrill implement IDirtyAware and also use the DirtyPropertyBehavior to flag when any change has been made.

public class BBQGrill : BindableType, INotifyDataErrorInfo, IDirtyAware
{
    public BBQGrill()
    {
        _changeBehaviors.Add(new DirtyPropertyBehavior(this));

Now, this is useful as we can key business logic off of the IsDirty property, however we can also bind to it in the UI which is just as useful.  Recall the Ideal Grill survey page from Metro BBQ.  We wanted to only enable the Save and Rest buttons once the user had made changes.  Now it’s easy to do so:

 <Button Content="Submit" Margin="10,0,10,0" IsEnabled="{Binding Grill.IsDirty}" />
 <Button Content="Reset" Margin="10,0,10,0"  IsEnabled="{Binding Grill.IsDirty}" />

This gives us the effect that we want in the UI for any property with extremely little code.

Screen default state:

buttonsdisabled

After changing one property:

buttonsenabled

Because of the way we structured Property Change Behaviors we just got a Binding-friendly “is dirty” behavior on all properties of the BBQGrill object.  Once we wrote the DirtyPropertyBehavior we got this essentially for free on all properties without writing extra code for every property.

Suspend Notifications

You may already be thinking of situations where you’d like to temporarily turn this property behavior off.  For example, you might be populating BBQGrill object values from a WCF service and obviously invoking property setters in that situation should not instantly mark the object as Dirty or this feature won’t be very useful.  You may have noticed that the IDirtyAware interface included a SuspendChangeNotification property and that the DirtyPropertyBehavior pays attention to this and does not set IsDirty when SuspendChangeNotification is set to true.  This solves the re-entrant problem but we can do a little better in terms of the developer experience around this code using a context class.

/// <summary>
/// Enable nice using(){} semantics for setting property values without firing Dirty state behaviors
/// </summary>
public class SuspendDirtyContext : IDisposable
{
    public SuspendDirtyContext(IDirtyAware target): this( new List<IDirtyAware> { target } )
    {
    }

    public SuspendDirtyContext(IEnumerable<IDirtyAware> targets)
    {
        _targets = targets;
        int index = 0;
        _targets.ForEach(d => 
        {
            _previousValues[index] = d.SuspendChangeNotification;
            d.SuspendChangeNotification = true;
            ++index;
        });
        _previousValues = new bool[_targets.Count()];
    }

    IEnumerable<IDirtyAware> _targets;
    bool[] _previousValues;

    public void Dispose()
    {
        int index = 0;
        _targets.ForEach(d =>
            {
                d.SuspendChangeNotification = _previousValues[index];
                ++index;
            });
    }
}

In C#, classes that implement IDisposable can be used in using() blocks.  While we’re not really getting rid of any resources here the syntactical sugar is too good to pass up. This SuspendDirtyContext allows us to write nice readable code like the following:

var bbqGrill = new BBQGrill();
using (var ctx = new SuspendDirtyContext(bbqGrill))
{
    //... set initial values
}

The using() block in C# winds up creating try/catch/finally semantics in IL, so even if something causes an exception to be thrown our object state won’t be wonky outside of this scope.  As you can see the SuspendDirtyContext can also handle more than one IDirtyAware instance. 

Conclusion

Knowing when a user has made a change to a data entity through the UI is a commonly requested and useful feature, and implementing it can be pretty easy with the right design of your data entities.  Using the Composition approach makes it very easy to turn this feature on and off for different objects or even different instances of the same type depending on your needs. 

There are still situations that can be easily supported using the same techniques we’ve already demonstrated and these will be explored in the following articles. 

Tags:

I&rsquo;m going to give you a Visual Studio 2010 Ultimate MSDN Subscription

by Administrator 5. July 2010 02:10

I have in hand a couple of one year MSDN Subscriptions with Visual Studio 2010 Ultimate.  Never you mind where they came from, but they didn’t fall of the back of a truck, they are legitimate. 

These are not for me, they are for YOU.  However, there are only two of these and according to my quick Twitter poll, a lot more than two people who’d like their own MSDN Ultimate.  Therefore, I pose to you a very simple contest.  Leave me a comment or send me an email telling me why you should get a subscription.  I will choose the winners late this week.

{Edit: I should be clear: I’m looking for community influencers here.  Tell me how this prize will touch more lives than just your own}

Tags:

2010 Microsoft MVP

by Administrator 2. July 2010 01:24

I am honored to be re-awarded the Microsoft MVP award in the Client App Dev competency.  As others have pointed out, re-awardees have to be vetted just like new awardees – no coasting!  I couldn’t have achieved this without all of you out there who keep reading my blog and inviting me back to your user groups, code camps, and conferences.  I have big plans for the next year so please keep coming back!

Cheers,

Damon

Tags:

About the author

Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

INETA Community Speakers Program

Month List

Page List

flickr photostream