DaedTech

Stories about Software

By

MS Test Report Generator v1.1

In the comments of this post, Kym pointed out that I had been remiss in providing instructions, so I’ve now corrected that state of affairs. I’ve uploaded v1.1 to SourceForge, and the zip file includes an MSI installer as well as PDF and DOCX formats of instructions.

As I alluded to in the comments of my previous post, I got a little carried away once I started on the instructions. I made a few minor modifications to the logic for generating reports, and added TRX as an additional, acceptable extension. That is the default extension for MS Test results files, but during the course of my build process, the files get renamed to .xml, so I didn’t have the .trx whitelisted in my validation routines. But now, I do.

The biggest change, though, is the addition of an interactive GUI, pictured here from SourceForge:

MS Test Report Generator

As I was adding instructions, it occurred to me that most people wouldn’t be following my build process, so I added a WPF project to my existing solution and set about making a GUI for this over the last week in my spare time. My over-engineered, layered implementation actually came in handy because this required very little in the way of changes to the underlying architecture. I just had to add logic to it for finding solutions and test files on disk, and the rest was sufficient.

The GUI isn’t perfect, but it’s pretty functional. If people like it, I’ll be happy to add to it (or you’re welcome to snag the source and contribute yourself if you want–it’s still available from the subversion repository). The gist is that you pick a solution and the tool will show you test runs for that solution. You then choose a test run and generate a report for it.

As I became my first user, I decided that it’d be interesting to have this open while developing, and that prompted me to add a “refresh” button so that I could do a test run, refresh, and generate a report for my latest run. In this fashion, I actually spent a few days developing where I’d view all my test results with this tool instead of the Visual Studio “Test Results” window.

There is plenty of room for extension, which I’ll do if people are interested. I could poll the filesystem for new tests instead of a manual refresh, for instance. But incremental baby steps. This is one of a bunch of pet projects that I have, so it’s not exactly as if I’m flush with time to get crazy with it. I’ll let the response level guide how much work I put in.

In that vein, if you like it or even if you don’t like it, but want me to do something to make you like it, send and email or post a comment here or on SourceForge! Aside from monitoring the SourceForge download content (and who knows what that really says about the project), that’s my only way of getting feedback.

By

WPF Combo Boxes

I thought I’d put together a quick post today on something that annoyed me and that I found unintuitive: binding with the WPF combo box. I’m doing some development following MVVM, and a situation came up in which I had a view model for editing a conceptual object in my domain. Let’s call it a user for the sake of this post, since the actual work I’m doing is nominally proprietary.

So, let’s say that user has a first name and a last name and that user also has a role. Role is not an enum or a literal, but an actual, conceptual reference object. In the view model for a customer edit screen, I was exposing a model of the user domain object for binding, and this model had properties like first name and last name editable via text box. I now wanted to add a combo box to allow for editing of the role by selecting one choice from a list of valid roles.

Forgetting the code for the presentation tier, I did this in the XAML:


Now, I’ve had plenty of occasions where I’ve exposed a list from a view model and then a separate property from the view model called “Selected Item.” This paradigm above would faithfully set my SelectedItem property to one of the list members. But here, I’m doing something subtly different. The main object in the view model–its focus–is UserModel. That is, the point of this screen is to edit the user, not roles or any other peripheral data. So, what I’m actually doing here is trying to bind a reference in another object to one of the items in the list.

What I have above didn’t work. And after a good bit of reading and head scratching, I figured out why. SelectedItem tries to find whatever it’s bound to in the actual list. In the case where I have a list in my view model and want to pick one of the members, this is perfect. But in the case where the list of roles contains objects that are distinct from the user’s role reference, this doesn’t work. The reason it doesn’t work, I believe, is that SelectedItem operates on equality. So if I were to create a list of roles and then assign one of them to the user model object, everything would be fine, since object equals defaults to looking for identical references. But in this case, where the list of roles and the user’s role are created separately (this is done in the data layer in my application) and have nothing in common until I try to match my user role to the list of roles, reference equals fails.

As an experiment, I tried the following:

public class Role
{
  public int Id { get; set; }
  
  public override bool Equals(object obj)
  {
    return Equals(obj as Role);
  }

  public bool Equals(Role role)
  {
    return role != null && role.Id == Id;
  } 
}

After I put this code in place, viola, success! Everything now worked. The combo box was now looking for matching IDs instead of reference equals. I packed up and went home (it was late when I was doing this). But on the drive home, I started to think about the fact that two roles having equal IDs doesn’t mean that they’re equal. ID is an artificial database construct that I hide from users for identifying roles. ID should be unique, and I have a bunch of unit tests that say that it is. But that doesn’t mean that equal IDs means conceptual equality. What if I somehow had two roles with the same ID but different titles, like, say, if I was allowing the user to edit the role title. If for some reason I wanted to compare the edited value with the new one using Equals(), I wouldn’t want the edited and original always to be equal simply because they shared an ID.

I figured I could amend the equals override, but I’m not big on adding code that I’m not actually using, and this is the only place I’m using Equals override. So I went back to the drawing board and read a bit more about the combo box. What I discovered was a couple of additional, rather unfortunately named properties: SelectedValue and SelectedValuePath. Here is what the amended working version looked like without overriding Equals:


ItemsSource is the same, but instead of a SelectedItem, I now have a “SelectedValue” and a “SelectedValuePath”. SelectedValue allows you to specify the binding target by a property of it, and SelectedValuePath allows you to specify which property of the members of ItemsSource should match SelectedValue.

So what the above is really saying is “I have a list of Roles. The role that’s selected is going to be whichever role in the list has an ID property that matches UserModel’s role ID.” And by default, when you change which value is selected, the UserModel’s “RoleId” gets updated with the new selection.

This actually somewhat resembles what I remember from doing Spring and JSP many moons ago, but there’s a little too much rust and probably too many JDKs and whatnot released between then and now for me to know that it’s current. When you actually get down to the nitty gritty of what’s going on, it is intuitive here. I just think the control’s naming scheme is a bit confusing. I would prefer something that indicated the relationship between the item and the list.

But I suppose lack of familiarity always breeds confusion, which in turn breeds frustration. Maybe now that I took the time to understand the nitty gritty instead of just copying what had worked for me in previous implementations, I’ll warm up to the naming scheme.

By

MVVM and Dialogs

For those familiar with the MVVM (Model, View, View-Model) pattern in .NET development, one conundrum that you’ve probably pondered, or at least read about, is what to do about showing a dialog. For a bit of background, MVVM is centered around the concept of binding from the View (XAML markup) to the “ViewModel”, which essentially acts as a staging platform for UI binding.

The ViewModel exposes the “Model” in such a way that the XAML can passively bind to it. It does this by exposing bindable properties (using INotifyPropertyChanged) and bindable commands (by using ICommand). Properties represent data, and commands represent actions.

The Problem

So, let’s say that you want a clean MVVM implementation which generally aspires to have no code-behind. Some people are more purist about this than others, but the concept has merit. Code-behind represents an active way of binding. That is, you have code that knows about the declarative markup and manipulates it. The problem here is that you have a dependency bugaboo. In a layered application, the layers should know about the one (or ones) underneath them and care nothing about the ones above them. This allows a different presentation layer to be plopped on a service tier or a different view to be skinned on a presentation tier. In the case of code-behind, what you have is a presentation tier that knows about its view and a view that knows about its presentation tier. You cannot simply skin another view on top because the presentation tier (read: code-behind) expects named elements in the declarative markup.

So, in a quest to eliminate all things code behind, you adopt MVVM and do fine when it comes to data binding and basic commands. But inevitably you want to open a window, and the WPF framework is extremely clunky and win-forms-like when it comes to this. Your choices, out of the box, are to have a named element in the XAML and manipulate it to show a dialog or else to have an event handler in the code behind.

What Others Have Suggested

The following are suggestions I’ve seen to address this problem and the reasons that I didn’t particularly care for them, in regards to my own situation. I did a fair amount of research before rolling my own.

  1. Just use the code behind (second response to post (3), though I’ve seen the sentiment elsewhere). I don’t really like this because I think that, when it comes to design guidelines, slippery slopes are a problem. If you’re creating a design where you’d like to be able to arbitrarily swap out groups of XAML files above a presentation layer, making this exception is the gateway to your skinnable plans going out the window. Why make exceptions to your guidelines if it isn’t necessary?
  2. Mediator Pattern. Well, this particular implementation lost me at “singleton,” but I’m not really a fan of this pattern in general for opening windows. The idea behind all of these is to create a situation where the View and ViewModel communicate through a mediator so as to have no direct dependencies. That is, ViewModel doesn’t depend on View–it depends on Mediator, as does the View. Generally speaking, this sort of mediation is effective at allowing tests and promoting some degree of flexibility, but you still have the same dependency in concept, and then you have the mediator code to maintain and manage.
  3. Behaviors. This is a solution I haven’t looked at too much and might come around to liking. However, at first blush, I didn’t like the looks of that extra XAML and the overriding of the Behavior class. I’m generally leery of .NET events and try to avoid them as much as possible. (I may create a post on that in and of itself, but suffice it to say I think the syntax and the forced, weakly typed parameters leave a lot to be desired.)
  4. Some kind of toolkit Blech. Nothing against the people that make these, and this one looks pretty good and somewhat in line with my eventual situation, but it seems like complete overkill to download, install, and maintain some third party application to open a window.
  5. IOC Container. I’ve seen some of these advertised, but the same principle applies here as the last one. It’s overkill for what I want to do.

I’ve seen plenty of other solutions and discussion as well, but none of them really appealed to me.

What I Did

I’ll just put the code and example usage in XAML here and talk about it:

public class OpenWindowCommand : SimpleCommand where T : Window, new()
{
    #region Fields

    /// Stores the function that evaluates whether or not the command can be executed
    private readonly Func _canExecute;

    /// View model that will serve as data context of the command in question
    private readonly IViewModel _viewModel;

    /// Used to verify method preconditions and object invariants
    private readonly ArgumentValidator _validator = new ArgumentValidator();
                                                                               

    #endregion

    #region Constructor

    /// For window open command, 
    /// 
    public OpenWindowCommand(IViewModel viewModel, Func canExecute = null) : base(canExecute, null)
    {
        _validator.VerifyNonNull(viewModel);

        _viewModel = viewModel;
    }

    #endregion

    #region ICommand stuff

    /// Ignores the command parameter, creates the window, sets its datacontext, and shows
    public override void Execute(object parameter)
    {
        var myWindow = new T();
        myWindow.DataContext = _viewModel;
        myWindow.ShowDialog();
    }

    #endregion
}

    

That’s it. The things that are referenced here that you won’t have are worth mentioning but not vital to the implementation. SimpleCommand, from which “OpenWindowCommand” inherits, is a class that allows easier command declaration and use. It implements ICommand. It takes a delegate or a boolean for CanExecute() and a delegate for execution (that we override in OpenWindowCommand since we have a concrete implementation). Simple command is not generic–the generic is in OpenWindowCommand to allow strongly typed window opening (the presumption here being that you want to use this for windows that you’ve created and want to show modally).

The binding in the XAML to commands is to an object that represents a collection of commands. I actually have a CommandCollection object that I’ve created and exposed as a property on the ViewModel for that XAML, but you could use a Dictionary to achieve the same thing. Basically, “Commands[]” is just an indexed hash of commands for brevity in the view model. You could bind to a OpenWindowCommand property on your ViewModel.

So, basically, when the view model from which you want to open a window is being setup, you create an instance of OpenWindowCommand(YourViewModelInstance). When you do this, you passively expose a window open for binding. You’re saying to the view “execute this command to open window of type X with view model Y for backing.” Your view users are then free to bind to this command or not.

Why I Like This

First of all, this implementation creates no code-behind. No named windows/dialogs certainly, but also no event handlers. I also like that this doesn’t have the attendant complexity of most of the other solutions that I’ve seen. There’s no IMediator/Mediator, there’s no ServiceLocator, no CommandManager.Instance–none of it. Just one small class that implements one framework interface.

Naturally, I like this because this keeps the ViewModel/presentation layer View agnostic. This isn’t true out of the box here, but it is true in my implementation. I don’t declare commands anywhere in my ViewModels (they’re all wired in configurably by my home-rolled IOC implementation at startup). So the ViewModel layer only knows about the generic Window, not what windows I have in my view.

Room for Improvement

I think it would be better if the presentation tier, in theory, didn’t actually know about Window at all. I’m keeping my eyes peeled for a way to remove the generic parameter from the class and stick it on the Execute() method to be invoked from XAML. XAML appears to be very finicky when it comes to generics, but I have some hope that this may be doable in the latest release. I’ll re-post when I find that, because I’d love to have a situation in which the XAML itself could specify what kind of window to open as a command parameter. (I’m not in love with command parameters, but I’d make an exception for this flexibility.)

I’m also aware that this doesn’t address non-modal windows, and that there is currently no mechanism for obtaining the result from ShowDialog. The former I will address as I grow the application that I’m working on. I already have a solution for the latter in my code, and perhaps I’ll detail that more in a subsequent post.

By

Directory Browser Dialog

One of the things that’s always surprised me about WPF is the lack of any kind of out-of-the-box file/directory browser dialog. It seems as though every time this comes up, I poke around the internet, hoping that it’s been added in some kind of update somewhere, but it never is. At least, it never is in the scope and skill of my google skills, anyway.

So, I wrote one for WPF. There’s nothing particularly hard about this, and I don’t view it as some kind of breakthrough. The reason that I’m making this post is that I noticed a trend that I find rather irritating. Whenever I’m searching for something like this, I seem to encounter two kinds of posts: posts that offer some zipped Visual Studio project I can download and plugin or else some vague, incomplete suggestion of what to do.

As for me personally, I’m just looking for functional code that I can slam right into my project. I don’t really want to download things and I don’t really want to spend the effort coding up something that I think should already exist. That is to say, I have no issue getting my hands dirty when I can learn something or customize, but I’m also not a big proponent of reinventing the wheel.

I’m posting here to break this trend that I noticed. This is a completely functional solution that exists not at all beyond what you see here. I’m hoping this appeals to people with tastes like mine. I like to see all the code but without downloading things.

So, without further ado:


    
        
    

Above is the XAML for the user control and below is the code behind

public partial class DirectoryDialog : UserControl
{

    /// This is to allow for binding of the directory path obtained by this control
    public static readonly DependencyProperty DirectoryPathProperty = DependencyProperty.Register("DirectoryPath", typeof(string), typeof(DirectoryDialog),
        new FrameworkPropertyMetadata((string)string.Empty, FrameworkPropertyMetadataOptions.AffectsRender));

    public string DirectoryPath { get { return (string)GetValue(DirectoryPathProperty) ?? string.Empty; } set { SetValue(DirectoryPathProperty, value); } }


    /// Initializes the directroy dialog user control and sets data context to self
    public DirectoryDialog()
    {
        InitializeComponent();
    }

    /// Handler for when user double clicks the file box
    /// I try to avoid code behind whenever possible.  Logic in declarative markup sucks for debugging and testing,
    /// and code behind is inherently hard to debug and test, but this is an exception.  I don't want this COM construct
    /// anywhere near something I'm planning to unit test. =) 
    private void HandleDoubleClick(object sender, MouseButtonEventArgs e)
    {
        using (var myDialog = new System.Windows.Forms.FolderBrowserDialog())
        {
            if (!string.IsNullOrEmpty(DirectoryPath))
            {
                myDialog.SelectedPath = DirectoryPath;
            }
            myDialog.ShowDialog();
            DirectoryPath = myDialog.SelectedPath;
        }
    }
}

An example user of this is here:


        
            
            
        

As you can see, this is about as simple as it gets. If I have use for it, I’ll probably later rename the control to something like ChooserDialog and allow it to have modes of “File” and “Directory” which pop up their respective kinds of dialogs. This could certainly be extended and made snazzier, and maybe I’ll do that with time. And, maybe when I do, I’ll post a link allowing people to download it, but I will also post the code so that you can inspect it without jumping through hoops, and you can see if it suits your needs.

By

WPF and Notifying Property Change

One of the central idioms of WPF development is having presentation tier classes implement the INotifyPropertyChanged interface. Anybody who has done more than a “Hello World” WPF application or two is almost certainly familiar with this and quite probably knows it like the back of his or her hand. As I’ve been learning WPF with C# over the past year (coming from a background of C++ and Java before that), my implementation of this has evolved a bit, and I thought I’d share the progression and my thoughts on why each subsequent implementation is an improvement.

By way of background, for anyone not familiar or looking for a refresher, this interface allows XAML bindings to keep in sync with the C# class. For instance, if you bound a XAML text box to a class property called “MyText”, the class containing MyText would implement INotifyPropertyChanged. This interface consists of just a single event, and properties fire the event when set. This is the mechanism by which the model (the thing being bound to) notifies the GUI that it should ask for an updated value. Without this, the GUI would display whatever value MyText had when it was loaded, and it would ignore subsequent changes that came from anywhere but the user modifying the text.

Here is literally the simplest implementation possible of INotifyPropertyChanged:

public class Model : INotifyPropertyChanged
{
    //This is all that the interface requires
    public event PropertyChangedEventHandler PropertyChanged;

    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            if(PropertyChanged != null)
                PropertyChange(this, new PropertyChangedEventArgs("Text")); 
        }
    }
}

So, whenever anyone (GUI or other code) invokes the setter for the Text field, the model class fires this event to notify the GUI (or anyone else listening) that the model’s Text has been changed. A popular, slight improvement on this would be to check that the value has actually been changed (that _text != value) before doing the setting or firing the event. The idea here is to prevent spurious event firing and thus spurious event handling.

The Basic Improvement

The first thing anybody is going to notice after implementing a few properties to back the UI is that each property setter requires an annoying amount of boilerplate. So, any Pragmatic Programmer would find a solution that didn’t involve all of this repetition–abstracting the boilerplate into a common method:

public class Model : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyChange(PropertyChangedEventArgs e)
    {
        if(PropertyChanged != null)
            PropertyChange(this, e); 
    }

    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyChange(new PropertyChangedEventArgs("Text"));
        }
    }
}

Clearly, this is better. You’ve eliminated two lines of code and a conditional from property setters. Amortized over an application, this will make the code more readable, more succinct, and easier to reason about.

What about all of those news

The next thing that will probably occur to someone after working with this for a while (or at least it did to me), is that it might not be necessary to create the same object every time a property is set. And that’s really what’s happening–you’re creating a new PropertyChangedEventArgs(), which is handed over to any event handler and then (probably) subsequently discarded. If you have a strange case in which someone is keeping that change event args around, then you can disregard this next optimization, though you might want to inquire why someone is storing that piece of communication artifice rather than whatever it may contain.

So the next solution I was introduced to (I didn’t actually come up with this on my own because I tend to be rather sparing in my use of “static”) is the following:

public class Model : INotifyPropertyChanged
{
    private void NotifyChange(PropertyChangedEventArgs e)
    {
        if(PropertyChanged != null)
            PropertyChange(this, e);
    }

    private string _text;
    private static PropertyChangedEventArgs _textArgs = new PropertyChangedEventArgs("Text");
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyChange(_textArgs);
        }
    }
}

Here, we’ve cut further down on the boilerplate in the setters, but, more importantly, we’re not allocating new objects on the heap with each property that’s set. Instead, there’s a static object initialized at application startup. You pay a one-time cost at startup, and then everything is much more efficient after that.

Tweaking the Optimization

After being shown this technique and using it for a while, I felt increasingly like something wasn’t quite right and there was room for improvement. Eventually, I put my fingers on two minor gripes. First, the property changed args were being created at application startup, for every property, whether or not anyone ever set it. Pedantically (though sometimes practically), this is not as efficient as it could be. It’s an improvement over creating on every set, but not as good as creating it the first time you need it. The second thing that bothered me is all of the boilerplate that went along with it. In the first step, we eliminated some boilerplate, and now, we’ve added it back into the mix. Instead of in our setter, it sits above our property.

To counter those two issues, I added a base class from which models (and ViewModels, if they expose properties directly) should inherit. If you don’t like a common ancestor like that, you could always implement this with an interface and a default behavior extension method on that interface, but I’m not a fan of extension methods for ‘extending’ your own code in your own assembly (extension methods just being syntactic sugar on free-floating static methods)

public abstract class ModelBase : INotifyPropertyChanged
{
    private readonly Dictionary<string, PropertyChangedEventArgs> _argsCache =
    new Dictionary<string, PropertyChangedEventArgs>();

    protected virtual void NotifyChange(string propertyName)
    {
        if (_argsCache != null)
        {
            if (!_ArgsCache.ContainsKey(propertyName))
                _argsCache[propertyName] = new PropertyChangedEventArgs(propertyName);

            NotifyChange(_argsCache[propertyName]);
        }
    }

    private void NotifyChange(PropertyChangedEventArgs e)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, e);
    }
}

public class Model : ModelBase
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyChange("Text");
        }
    }
}

What’s going on here is that we maintain a cache of EventArgs. Whenever a property change notification fires, the cache is checked for the corresponding event arguments. If they don’t exist, you new them up, but if they do, then this behaves like our static one. The end effect is that, for the life of the object, you get the benefit from the previous example of a single creation and the additional benefit of not taking a huge hit at application startup for all (and some potentially unneeded) properties. This suffers, performance wise, if you implement it on a lot of short lived models, because you might then, in effect, be newing all the time. The tradeoff is probably worth it if you have a high ratio of model modification to model creation. In my case, I do.

What About Those Magic Strings?

If you’re like me, the presence of “Text” everywhere in this set of examples has been like a little pebble stuck in your shoe. It’s annoying enough to irritate, but not necessarily quite annoying enough to fix at the moment. However, continuing the silly metaphor, you eventually hit your breaking point, wrench off your shoe, and do something about it. With the magic strings, that came a few months back.

I poked around on the internet some and saw various people’s solutions to this. None of them were quite to my liking, so I cobbled together one of my own from assorted pieces and my own style of coding. I don’t have any links because I honestly don’t recall where I found them and which parts would be attributable to whom. So, just be aware that not all of the thinking was entirely from scratch and that if you find somebody’s code that looks, in part, like this, there’s a good chance that’s where I got part of the idea.

public abstract class ModelBase : INotifyPropertyChanged
{
    private readonly Dictionary _argsCache = new Dictionary();

    protected virtual void NotifyChange<T>(Expression<Func<T>>propertySelector)
    {
        var myName = GetMemberName<T>(propertySelector);
        if (!string.IsNullOrEmpty(myName))
            NotifyChange(myName);
    }

    protected virtual void NotifyChange(string propertyName)
    {
        if (_argsCache != null)
        {
            if (!_argsCache.ContainsKey(propertyName))
                _argsCache[propertyName] = new PropertyChangedEventArgs(propertyName);

            NotifyChange(_argsCache[propertyName]);
        }
    }

    private void NotifyChange(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null) 
            PropertyChanged(this, e);
    }
}

public class Model : ModelBase
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyChange(() => Text);
        }
    }
}

This is a lot more involved, and I won’t go into all of the gory details here. But, suffice it to say, I’m taking advantage of a concept called early binding. The “automagic” way that WPF binds its XAML to your properties is through reflection in the framework. It sees {Binding Text} and it goes looking on the data context for a property called “Text”. When it finds that, it invokes ToString() on it, and that’s what appears in the GUI. For notifying change, the same thing happens. It takes “Text” from your event args and goes looking for a match in the XAML.

This is called “late binding.” You are trusting at runtime that the WPF runtime is going to be able to match your two constructs through reflection. A typo, “text” instead of “Text”, for instance, will not stop the application from building or event trigger a compiler warning. The IDE is perfectly happy to let you make as many of these mistakes as you can manage. It won’t even throw a runtime exception. You’ll just get weird results and have to pick through the output window looking for XAML problems (or painstakingly match your XAML to your Notification arguments).

With Early binding, we eliminate that. The expression that you’re passing to NotifyChange() is typesafe and compiler-checked. This means that you need to pass it an actual property or it will not compile. Now, it’s possible that you’re going to have a “Text” and a “Txet” or “text” property, but it’s not very likely, and, if you do, you may want to reconsider your naming schemes. Since you’re now binding your notification to its property at build time rather than using reflective indirection through the WPF framework, you’re a lot less prone to mistakes.

I should point out here that you are introducing extra reflection, which means you’ll take a bit of a performance hit. However, I’ve never found it to be noticeable (I have never done a time trial on it, though), and I think the tradeoff in whatever performance hit you take is well worth the hours, days, and weeks you don’t lose to tracking down obscure typos in XAML or property notifications months after they happen. Besides, the WPF framework relies heavily on reflection anyway, so you’re just adding to the paradigm slightly. If you’re using WPF, you’re probably not logging your response times in microseconds anyway.

Conclusion

So, that’s it. That’s the evolution of how I notify the GUI that things have changed. If you have a suggestion for improvement, I’d be happy to add another step to the mix. I’m always looking to improve and find slicker, more elegant ways to do things.

By the way, if you liked this post and you're new here, check out this page as a good place to start for more content that you might enjoy.