Blog

  • 10% Project

    10% Project

    Google are well known for their attitude towards encouraging employee creativity. So much so they have an initiative that allows all(?) employees to spend 20% of their time working on personal interest projects.

    A 20% project can be anything that sparks interest for the individual, in general they are usually something to do with improving the way that they are working, or the software they are using.

    I read today that over 50% of the google product line up have come from 20% projects – including gmail!

    Anyway I’ve wanted to do this ever since I found out about it, and now that I’m working for myself again the time has come to do it. I can’t quite afford 20% yet, but 10% will do. A day every fortnight focussed on learning new a tech, doing some design work or building a fanciful site. And not worrying about revenue generation or payment. That’ll do nicely!

  • Paperless Home

    Paperless Home

    Many, many years ago I had a flatbed scanner and that scanner had a gnatty ‘scan-to-email’ function that would email any scans as a PDF attachment.

    Many years later (but still many years ago) I signed up for the Google Documents online service and registered for their Email to Documents service. This was a hashed email address that would save attachments into the Google Docs cloud (and convert them if you wish).

    This combination of scan to email to cloud has had me literally salivating for years – it puts the paperless office within everyone grasp. So, finally after much procrastination I have finally got my act together, brought a duplex scanner (HP Officejet Pro 8500A Plus e-All-in-One Web Enabled Printer ), with a wireless internet connection ready to put my master plan in to action…

    After unboxing, what should I find?? A flipping Google Docs Storage Application! Yep, the scanner comes with a prebuilt in application that does exactly what I wanted… So, have I now got a paperless office? Well no, because the scanner also has a lovely printer function too, and to not use that would be a waste

  • .NET Assembly Versioning

    .NET Assembly Versioning

    A colleague recently asked me the difference between the different version properties available in a .NET assembly. I had read about this recently in Jeff Richters outstanding CLR via C# but couldn’t remember the semantics off the top of my head.

    • AssemblyFileVersion: The version number you want the public to see. Ideally you’d want the build tool (e.g. CSC.exe or AL.exe) to automatically update the build and revision number number, but this doesn’t happen. This version number can be seen when using Windows Explorer and is typically used to identify a specific assembly version when trouble shooting.
    • AssemblyInformationalVersion: This version number is stored in the Win32 version resource and is for informational purposes. This number exists to indicate which version of the product includes this assembly.
    • AssemblyVersion: This value is stored in the AssemblyDef manifest metadata table. THe CLR uses this version number when binding to strongly named assemblies. This number is used to uniquely identify an assembly, and is used to tightly bind the assembly as a reference within a product.
  • Silverlight Deferred / Delayed Selected Date Picker

    Silverlight Deferred / Delayed Selected Date Picker

    When implementing a date picker that is used to fetch some ‘details’ based on the selected date, the chances are that you don’t want to begin fetching the ‘details’ immediately.

    If you did, and made a rapid change to the SelectedDate (maybe holding down an arrow key), the asynchronous fetch will be repeated a large number of times.

    To prevent this, implement a deferral on the selected date change, for example:

    public class DeferredDP : DatePicker {
    
    public DeferredDP() {
    this.DefaultStyleKey = typeof(DatePicker);
    base.SelectedDateChanged += new EventHandler(DeferredDP_SelectedDateChanged);
    }
    
    DispatcherTimer _timer;
    
    void DeferredDP_SelectedDateChanged(object sender, SelectionChangedEventArgs e) {
    /// if there is an instance of the timer already running stop it.
    if (_timer != null) {
    _timer.Stop();
    _timer = null;
    }
    
    /// only trigger the selection changed event when the date has been changed
    if (e.AddedItems.Count == 1 &&
    e.AddedItems[0] is DateTime) {
    
    if (SelectionDelay.HasValue) {
    /// if the timer delay has been set, delay the setting of the value
    _timer = new DispatcherTimer();
    _timer.Interval = new TimeSpan(0,0,0,0,SelectionDelay.Value);
    _timer.Tick += (s1, e1) => {
    SetValue(SelectedDateDeferredProperty, (DateTime)e.AddedItems[0]);
    if (_timer != null) {
    _timer.Stop();
    _timer = null;
    }
    };
    _timer.Start();
    } else { // if the timer delay is not set, set the property immediately.
    SetValue(SelectedDateDeferredProperty, (DateTime)e.AddedItems[0]);
    }
    }
    }
    
    ///
    /// Milliseconds delay before the selected date value is updated.
    ///
    public int? SelectionDelay {
    get { return (int?)GetValue(SelectionDelayProperty); }
    set { SetValue(SelectionDelayProperty, value); }
    }
    
    public static readonly DependencyProperty SelectionDelayProperty =
    DependencyProperty.Register("SelectionDelay", typeof(int?), typeof(DeferredDP), new PropertyMetadata(null));
    
    public DateTime? SelectedDateDeferred {
    get { return (DateTime?)GetValue(SelectedDateDeferredProperty); }
    set { SetValue(SelectedDateDeferredProperty, value); }
    }
    
    public static readonly DependencyProperty SelectedDateDeferredProperty =
    DependencyProperty.Register("SelectedDateDeferred", typeof(DateTime?), typeof(DeferredDP), new PropertyMetadata(null, SelectedDateDeferredChanged));
    public static void SelectedDateDeferredChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) {
    DeferredDP instance = d as DeferredDP;
    
    if (instance.SelectedDateDeferred != instance.SelectedDateDeferred) {
    instance.SelectedDateDeferred = instance.SelectedDateDeferred;
    }
    
    }
    }
    
  • MSDTC

    MSDTC

    We had some really strange problems getting MSDTC to work recently, specifically upgrading to VS2010 and SL4. Our developer environments are pointing to networked database servers and during this particular use-case the development workstation is running a both the hosted Silverlight Client and the Business Logic (API) served through a WCF service (both in Cassini). The API is performing the transactional logic.

    So, working through the bugs and error messages that we got;

    The first error requires MSDTC to be started (which is wasn’t by default):

    The transaction manager has disabled its support for remote/network transactions. Both the WCF Server (in our case the developer workstation) and the Database Server have to have MSDTC running. Start MSDTC using the command line: NET START MSDTC

    YMMV, but on Win7 the default properties for DTC also had to be updated. From Component Services MMC, navigate to Computers | My Computer | Distributed Transaction Coordinator | Local DTC. Right click + Properties and set as follows:

    clip_image002

    Next error then relates to the default firewall setting:

    The MSDTC transaction manager was unable to pull the transaction from the source transaction manager due to communication problems. Possible causes are: a firewall is present and it doesn’t have an exception for the MSDTC process, the two machines cannot find each other by their NetBIOS names, or the support for network transactions is not enabled for one of the two transaction managers. Sometimes we didn’t get this exception, and got a timeout instead and the failed transaction could be seen in the outstanding transactions list.

    To resolve this we updated the Windows Firewall to add an inbound and outbound tunnel for %SystemRoot%\System32\msdtc.exe

    All seems to OK … for now… :S

  • Silverlight Tab Stops – IsTabStop

    Just found a tricky little quirk with TabStop that caused a fair bit of confusion. It turns out that the default implementation of ContentControl overrides Control, so implements the IsTabStop property, and defaults that value to true.

    ContentControl is implemented by the delightful BusyIndicator, so if you have used a BusyIndicator within the scope of a series of input controls you’ll see the Invisible Tab Stop behaviour.

    HINT: Using Silverlight Spy shows us where the offending property lies. You’ll need to re-template that to set the IsTabStop property to false.