<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:thr="http://purl.org/syndication/thread/1.0">
    <title type="text">Paul Stovell</title>
    
    <link rel="alternate" href="http://www.paulstovell.com/" type="text/html" />
    <subtitle>Paul Stovell's thoughts on WPF and client architecture.</subtitle>
    <updated>2009-11-05T10:57:26Z</updated>
    <id>http://www.paulstovell.com/feeds/rss</id>
    <creativeCommons:license>http://www.creativecommons.org/licenses/by-nc/2.5/rdf</creativeCommons:license>
    

    <link rel="self" href="http://feeds.feedburner.com/paulstovell" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
        <id>http://www.paulstovell.com/magellan</id>
        <title type="text">Magellan</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/magellan" />
        <published>2009-10-25T13:48:39Z</published>
        <updated>2009-10-25T13:48:39Z</updated>
        
    <content type="html">
        
        &lt;div style="float: right;"&gt;
   &lt;img src="http://www.paulstovell.com/get/magellan/magellan.jpg" /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Magellan&lt;/strong&gt; is a lightweight framework that makes it easy to build &lt;a href="/wpf-navigation"&gt;WPF navigation&lt;/a&gt; applications. It is inspired by the ASP.NET MVC framework. The main features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model-View-Controller support&lt;/li&gt;
&lt;li&gt;Action filters for cross-cutting concerns such as authorization and redirection&lt;/li&gt;
&lt;li&gt;Blend behaviors to make navigation easy&lt;/li&gt;
&lt;li&gt;Transitions between pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Magellan was drawn from a number of samples I had put together early this year and some work done on a client project. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://get.paulstovell.com/magellan"&gt;Download the library&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://get.paulstovell.com/magellan"&gt;Download the source code (with sample application)&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The source download includes an "iPhone" application for demonstrating the features.&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/magellan/iphone-sample.png" alt="The sample iPhone application" /&gt;&lt;/p&gt;

&lt;p&gt;We start with a simple project structure:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/magellan/project-structure.png" alt="A VS2008 project with a number of folders for controllers, models and views" /&gt;&lt;/p&gt;

&lt;p&gt;A controller implementation typically looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class PhoneController : Controller
{
    public ActionResult Group(Group group)
    {
        var contacts = _contactRepository.GetContacts(group);

        Model = new GroupViewModel(group.Name, contacts);
        return View();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Views are XAML Page objects, and can optionally have a model. Here's an example:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/magellan/view-models.png" alt="View models" /&gt;&lt;/p&gt;

&lt;p&gt;The idea is that upon navigation, a controller is created, the action is executed, and the view and view model are created. The view then becomes the focus of the frame. Put simply, the view and viewmodel are stateful, and the controller is stateless. &lt;/p&gt;

&lt;p&gt;Navigation between views (with nice transitions) can be done either programatically:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Navigator.For(Frame).NavigateWithTransition("Home", "Main", "ZoomOut");
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or through Blend behaviors:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/magellan/blend-navigate-behavior.PNG" alt="Blend Navigate behavior" /&gt;&lt;/p&gt;

&lt;p&gt;The framework supports the ASP.NET MVC concepts of Action Filters, Model Binders, View Engines and more - I'll cover them in a later post.&lt;/p&gt;

        &lt;img src="http://www.paulstovell.com/magellan/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JoMvfzwT5mw:6wF-5OsLJA8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JoMvfzwT5mw:6wF-5OsLJA8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JoMvfzwT5mw:6wF-5OsLJA8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=JoMvfzwT5mw:6wF-5OsLJA8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

    <entry>
        <id>http://www.paulstovell.com/enforced-strings</id>
        <title type="text">Enforced Strings</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/enforced-strings" />
        <published>2009-10-09T13:02:24Z</published>
        <updated>2009-10-09T13:02:24Z</updated>
        
    <content type="html">
        
        &lt;p&gt;Enterprise applications typically deal with many categories of strings. Human names, reference codes, SKU identifiers, email addresses - the list is huge. There are subtle rules that apply to many of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whitespace at the start and end of many strings should probably be ignored &lt;/li&gt;
&lt;li&gt;Human names probably shouldn't contain newlines, tab characters, the percentage symbol, or 27 dashes in a row&lt;/li&gt;
&lt;li&gt;For some strings, casing makes no difference when deciding equality, and sometimes it does&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's common to litter our code with these assumptions, which leads to inconsistency. Sometimes we assume that the UI will handle all of these issues, and the domain layer will simply use what it's given. &lt;/p&gt;

&lt;p&gt;Recently I have started experimenting with creating custom strings to encapsulate a lot of these subtle things. On my blog, when you browse to a URL like &lt;a href="/enforced-strings"&gt;/enforced-strings&lt;/a&gt;, instead of the page name being passed around as a string, it's passed as a PageName object. PageName supports implicit conversion operators, so it can be dealt with as a regular string too. Here is part of a unit test:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PageName expected = "hello-world";

// When cast to a PageName, each of these should be converted into the above
var logicallySameAsExpected = new string[] {
    "hello-world",
    "hello-worLD",
    " hello -world ",
    " hello$-world ",
    " hello $-world ",
    " hello-$-world ",
    " hello world ",
    " -   hello   world   - ",
    " -   HeLLo  WoRLD  - ",
    " -   HeLLo  %^@#@#*()[]WoRLD  - ",
    " -   HeLLo  %^@#@#*()[]WoRLD  - $%",
    "@# -   HeLLo  %^@#@#*()[]WoRLD  - $%"
};

foreach (var match in logicallySameAsExpected)
{
    var castMatch = (PageName) match;
    Assert.AreEqual(expected, castMatch);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The assumption I make with PageName is that while it may be instantiated with dirty input (a malformed URL, for example), I can probably infer what was meant. PageName is used throughout my domain model and even at the data access layer - in my case, I use a custom &lt;a href="http://svn.paulstovell.com/svn/PaulPad/Source/PaulPad.Web/Model/Mappings/UserTypes/PageNameUserType.cs"&gt;IUserType&lt;/a&gt; with NHibernate to treat strings from the database as page names.&lt;/p&gt;

&lt;p&gt;To build your own enforced strings, here are the key things to consider doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a class to wrap a real string&lt;/li&gt;
&lt;li&gt;Make it immutable, and ideally sealed&lt;/li&gt;
&lt;li&gt;In the constructor, massage the input string&lt;/li&gt;
&lt;li&gt;Override all of the equality operators, GetHashCode, etc., and implement IEquatable, and IComparable&lt;/li&gt;
&lt;li&gt;Override ToString (obviously)&lt;/li&gt;
&lt;li&gt;Add an implicit cast operator to automatically convert from your string to real strings and back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see an example of this in PaulPad - first I setup a &lt;a href="http://svn.paulstovell.com/svn/PaulPad/Source/PaulPad.Web/Model/Strings/EnforcedString.cs"&gt;base class with most of the overloads&lt;/a&gt;, then I &lt;a href="http://svn.paulstovell.com/svn/PaulPad/Source/PaulPad.Web/Model/Strings/PageName.cs"&gt;inherit from that to setup the specific string type&lt;/a&gt;. &lt;/p&gt;

        &lt;img src="http://www.paulstovell.com/enforced-strings/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=1MSBTAQdKoE:_i0BT8CtAsA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=1MSBTAQdKoE:_i0BT8CtAsA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=1MSBTAQdKoE:_i0BT8CtAsA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=1MSBTAQdKoE:_i0BT8CtAsA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

    <entry>
        <id>http://www.paulstovell.com/jquerypad</id>
        <title type="text">jQueryPad</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/jquerypad" />
        <published>2009-10-08T15:19:11Z</published>
        <updated>2009-10-08T15:19:11Z</updated>
        
    <content type="html">
        
        &lt;p&gt;jQueryPad is a fast JavaScript and HTML editor. Just start it, enter the HTML you want to work with, bash in your jQuery code, and hit F5 to see the results. Say goodbye to ALT+TAB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://get.paulstovell.com/jQueryPad/jQueryPad.zip"&gt;Download&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/jquerypad/jQueryPad.PNG" alt="jQueryPad screenshot" /&gt;&lt;/p&gt;

&lt;p&gt;jQueryPad is xcopy deployable. It's written in WPF and uses the Web Browser Control to embed Internet Explorer for testing the script. When you press F5, the HTML and JavaScript are combined into one file and rendered. The template also references jQuery, so the jQuery functions are available.&lt;/p&gt;

&lt;p&gt;If you want to use a different version of jQuery or reference other files, just replace the files in the Templates directory. &lt;/p&gt;

&lt;p&gt;Hope you find it useful - feature suggestions are welcome. &lt;/p&gt;

        &lt;img src="http://www.paulstovell.com/jquerypad/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=IbXVuyOB7Lw:GT65myuDQ4E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=IbXVuyOB7Lw:GT65myuDQ4E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=IbXVuyOB7Lw:GT65myuDQ4E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=IbXVuyOB7Lw:GT65myuDQ4E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

    <entry>
        <id>http://www.paulstovell.com/sheldon</id>
        <title type="text">Sheldon</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/sheldon" />
        <published>2009-10-07T12:16:53Z</published>
        <updated>2009-10-07T12:16:53Z</updated>
        
    <content type="html">
        
        &lt;p&gt;&lt;strong&gt;Sheldon&lt;/strong&gt; is a WPF command line control, and code to integrate it with IronPython. It's designed as a sample that demonstrates how a WPF application might be made scriptable:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/sheldon/Sheldon-Window-Control.png" alt="A screenshot of Sheldon" /&gt;&lt;/p&gt;

&lt;p&gt;This sample was created to pitch an idea to a client about enabling a macro system in their application. Users might be able to make use of functions like &lt;code&gt;OpenAccount("ACME")&lt;/code&gt;, &lt;code&gt;ExecuteJob("SalesForecast2009")&lt;/code&gt;, and so on. Using the Command Pattern, commands could be written to an Output window in the application while the user uses the UI - that could be used as a learning tool for learning the command line. &lt;/p&gt;

&lt;p&gt;The demo application shows how object models can be shared between your application and scripting environment. In C#, I set up an AutomationContext, which is made available to IronPython:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class AutomationContext
{
    public ApplicationDefinition Application { get; set; }
    public IScriptingContext ScriptingContext { get; set; }

    public void Exit()
    {
        Environment.Exit(0);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then in IronPython, I create a friendly "API" that users can consume:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def GetWindow(name):
    return automation_context.Application.MainWindow
def Clear():
    automation_context.ScriptingContext.Clear()
def Exit():
    automation_context.Exit()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;ScriptingContext&lt;/code&gt; is an object that manages the execution and rendering of scripts, which the command line control can hook into. Multiple controls can talk to a single scripting context - here's a custom shell (I simply overrode the style and control template of the Shell control):&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/sheldon/Sheldon-Custom-Shell.PNG" alt="A custom shell style and template" /&gt;&lt;/p&gt;

&lt;p&gt;You can download the code here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ZIP: &lt;strong&gt;&lt;a href="http://get.paulstovell.com/Samples/Sheldon.zip"&gt;Sheldon.zip&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;SVN: &lt;a href="http://svn.paulstovell.com/svn/Samples/Sheldon/"&gt;/svn/Samples/Sheldon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

        &lt;img src="http://www.paulstovell.com/sheldon/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JduPJXCS4as:M_p-B2j_sjM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JduPJXCS4as:M_p-B2j_sjM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=JduPJXCS4as:M_p-B2j_sjM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=JduPJXCS4as:M_p-B2j_sjM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

    <entry>
        <id>http://www.paulstovell.com/editable-collection-adapter</id>
        <title type="text">Editable Collection Adapter for WPF</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/editable-collection-adapter" />
        <published>2009-10-02T07:15:06Z</published>
        <updated>2009-10-02T07:15:06Z</updated>
        
    <content type="html">
        
        &lt;p&gt;The screenshot below is of a sample WPF application that deals with editing a collection of items:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/editable-collection-adapter/editable-collection.PNG" alt="The editable collection" /&gt;&lt;/p&gt;

&lt;p&gt;A few features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can make a batch of changes to the screen and hit "Save". &lt;/li&gt;
&lt;li&gt;If you deleted items, you can click "Show deleted items" to make them visible again, then click Undo to rollback the deletion&lt;/li&gt;
&lt;li&gt;The list on the left is bound to the same collection as the list on the right - the changes aren't written to the source until you click Save&lt;/li&gt;
&lt;li&gt;If you change an item, it highlights in bold&lt;/li&gt;
&lt;li&gt;If you change an item, you can undo the changes via the Undo button&lt;/li&gt;
&lt;li&gt;If you add items to the original collection, they will appear on screen (the Remote Update button)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The object representing an individual row is just a simple POCO object with &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; support - it has no &lt;code&gt;HasChanges&lt;/code&gt; property or similar. Likewise, the collection is just an &lt;code&gt;ObservableCollection&amp;lt;T&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is all implemented with a mix of &lt;a href="/bindable-linq"&gt;BindableLINQ&lt;/a&gt; and the &lt;a href="/editable-object-adapter"&gt;Editable Object Adapter&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://get.paulstovell.com/Samples/WPF%20EditableCollection.zip"&gt;Download&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note: This sample uses the Xceed WPF DataGrid control. If you have a license, you can use your license key when running the sample (just set it in App.xaml.cs). Alternatively, you can download a &lt;a href="http://xceed.com/pages/TopMenu/Downloads/Trials.aspx?Lang=EN-CA"&gt;45 day trial from the Xceed website&lt;/a&gt;.&lt;/p&gt;

        &lt;img src="http://www.paulstovell.com/editable-collection-adapter/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=riXtq35Wdfs:A1-7rQCSNto:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=riXtq35Wdfs:A1-7rQCSNto:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=riXtq35Wdfs:A1-7rQCSNto:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=riXtq35Wdfs:A1-7rQCSNto:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

    <entry>
        <id>http://www.paulstovell.com/wpf-delaybinding</id>
        <title type="text">DelayBinding: a custom WPF Binding</title>
        <author><name>Paul Stovell</name></author>
        <link rel="alternate" href="http://www.paulstovell.com/wpf-delaybinding" />
        <published>2009-10-02T01:58:18Z</published>
        <updated>2009-10-02T01:58:18Z</updated>
        
    <content type="html">
        
        &lt;p&gt;When you use the Outlook 2007 search, Vista's start search, or the Search bar in Explorer, there's often a short delay between when you press a key, and when the search begins. &lt;/p&gt;

&lt;p&gt;In WPF, we could simulate this through a series of event handlers, timers and code-behind directly on controls, but we usually want to be able to use this alongside WPF's data binding capabilities. To use WPF data binding in a delayed fashion, I created a simple &lt;a href="http://joshsmithonwpf.wordpress.com/2007/05/25/a-review-of-markup-extensions/"&gt;markup extension&lt;/a&gt; which creates a binding and manages the timer delay between commits. &lt;/p&gt;

&lt;p&gt;Here's how you can use it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;TextBox Text="{z:DelayBinding Path=SearchText}" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also set an explicit delay. By default, it uses 0.5 seconds, which felt consistent with Outlook, though I didn't spend that much time working out exactly how long Outlook waits. I did look to see if there was a &lt;strong&gt;SystemParameters&lt;/strong&gt; class for something like "SearchDelay", but couldn't find one. Suggestions for a better default are welcome. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;TextBox Text="{z:DelayBinding Path=SearchText, Delay='00:00:01'}" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead of creating a new type of Binding, I'm using the standard WPF Binding, but setting the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.data.updatesourcetrigger.aspx"&gt;UpdateSourceTrigger&lt;/a&gt; to Explicit. As the text changes, the timer is reset, and when it ticks the value is pushed to the source. &lt;/p&gt;

&lt;p&gt;&lt;img src="/get/delay-binding/delay-binding-before.png" alt="Delay binding - as the user types, the results do not change" /&gt;&lt;/p&gt;

&lt;p&gt;After the short delay:&lt;/p&gt;

&lt;p&gt;&lt;img src="/get/delay-binding/delay-binding-after.png" alt="...but after the short delay, the results change" /&gt;&lt;/p&gt;

&lt;p&gt;First, the code to the markup extension (XML-doc comments removed):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[MarkupExtensionReturnType(typeof(object))]
public class DelayBindingExtension : MarkupExtension
{
    public DelayBindingExtension()
    {
        Delay = TimeSpan.FromSeconds(0.5);
    }

    public DelayBindingExtension(PropertyPath path) 
        : this()
    {
        Path = path;
    }

    public IValueConverter Converter { get; set; }
    public object ConverterParamter { get; set; }
    public string ElementName { get; set; }
    public RelativeSource RelativeSource { get; set; }
    public object Source { get; set; }
    public bool ValidatesOnDataErrors { get; set; }
    public bool ValidatesOnExceptions { get; set; }
    public TimeSpan Delay { get; set; }
    [ConstructorArgument("path")]
    public PropertyPath Path { get; set; }
    [TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
    public CultureInfo ConverterCulture { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var valueProvider = serviceProvider.GetService(typeof (IProvideValueTarget)) as IProvideValueTarget;
        if (valueProvider != null)
        {
            var bindingTarget = valueProvider.TargetObject as DependencyObject;
            var bindingProperty = valueProvider.TargetProperty as DependencyProperty;
            if (bindingProperty == null || bindingTarget == null)
            {
                throw new NotSupportedException(string.Format(
                    "The property '{0}' on target '{1}' is not valid for a DelayBinding. The DelayBinding target must be a DependencyObject, "
                    + "and the target property must be a DependencyProperty.", 
                    valueProvider.TargetProperty, 
                    valueProvider.TargetObject));
            }

            var binding = new Binding();
            binding.Path = Path;
            binding.Converter = Converter;
            binding.ConverterCulture = ConverterCulture;
            binding.ConverterParameter = ConverterParamter;
            if (ElementName != null) binding.ElementName = ElementName;
            if (RelativeSource != null) binding.RelativeSource = RelativeSource;
            if (Source != null) binding.Source = Source;
            binding.ValidatesOnDataErrors = ValidatesOnDataErrors;
            binding.ValidatesOnExceptions = ValidatesOnExceptions;

            return DelayBinding.SetBinding(bindingTarget, bindingProperty, Delay, binding);
        }
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the &lt;strong&gt;DelayBinding&lt;/strong&gt; class, which as you can see above is being instantiated by the &lt;strong&gt;DelayBindingExtension.&lt;/strong&gt; You could also create it manually in code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class DelayBinding
{
    private readonly BindingExpressionBase _bindingExpression;
    private readonly DispatcherTimer _timer;

    protected DelayBinding(BindingExpressionBase bindingExpression, DependencyObject bindingTarget, DependencyProperty bindingTargetProperty, TimeSpan delay)
    {
        _bindingExpression = bindingExpression;

        // Subscribe to notifications for when the target property changes. This event handler will be 
        // invoked when the user types, clicks, or anything else which changes the target property
        var descriptor = DependencyPropertyDescriptor.FromProperty(bindingTargetProperty, bindingTarget.GetType());
        descriptor.AddValueChanged(bindingTarget, BindingTarget_TargetPropertyChanged);

        // Add support so that the Enter key causes an immediate commit
        var frameworkElement = bindingTarget as FrameworkElement;
        if (frameworkElement != null)
        {
            frameworkElement.KeyUp += BindingTarget_KeyUp;
        }

        // Setup the timer, but it won't be started until changes are detected
        _timer = new DispatcherTimer();
        _timer.Tick += Timer_Tick;
        _timer.Interval = delay;
    }

    private void BindingTarget_KeyUp(object sender, KeyEventArgs e)
    {
        _timer.Stop();
        if (e.Key == Key.Enter) _bindingExpression.UpdateSource();
    }

    private void BindingTarget_TargetPropertyChanged(object sender, EventArgs e)
    {
        _timer.Stop();
        _timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        _timer.Stop();
        _bindingExpression.UpdateSource();
    }

    public static object SetBinding(DependencyObject bindingTarget, DependencyProperty bindingTargetProperty, TimeSpan delay, Binding binding)
    {
        // Override some specific settings to enable the behavior of delay binding
        binding.Mode = BindingMode.TwoWay;
        binding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;

        // Apply and evaluate the binding
        var bindingExpression = BindingOperations.SetBinding(bindingTarget, bindingTargetProperty, binding);

        // Setup the delay timer around the binding. This object will live as long as the target element lives, since it subscribes to the changing event, 
        // and will be garbage collected as soon as the element isn't required (e.g., when it's Window closes) and the timer has stopped.
        new DelayBinding(bindingExpression, bindingTarget, bindingTargetProperty, delay);

        // Return the current value of the binding (since it will have been evaluated because of the binding above)
        return bindingTarget.GetValue(bindingTargetProperty);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I imagine this would be useful for Silverlight, but since Silverlight does not support custom &lt;strong&gt;MarkupExtensions&lt;/strong&gt;, and since Silverlight Binding's can't have an UpdateSourceTrigger (to set it to Explicit), I expect you would end up creating it through an attached dependency property and triggering the binding to push manually. Let me know if you write one. &lt;/p&gt;

        &lt;img src="http://www.paulstovell.com/wpf-delaybinding/via-feed" /&gt;
        
        &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=Wr7nORQ8KKw:9xtD2IziQVM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=Wr7nORQ8KKw:9xtD2IziQVM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulstovell?a=Wr7nORQ8KKw:9xtD2IziQVM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulstovell?i=Wr7nORQ8KKw:9xtD2IziQVM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content></entry>

</feed>
