Saturday, March 20, 2010

As I’ve said before, I love Windows Home Server. While it has many useful features, the core feature is automatic nightly image backups of my computers.

Of course a backup is only useful if you can do a restore, which I’ve done 2-3 times, and which has easily paid for WHS each time.

I recently got my PDC laptop (Acer Aspire 1420P) into a bad spot with some pre-release software. This happens, and I wasn’t worried because I have WHS backups. Just 60-90 minutes and I can have the machine back exactly the way it was at a previous point in time.

Except I ran into a snag. It turns out that the WHS restore CD from 2007 bluescreens when it tries to boot on the 1420P. OK, no problem, I downloaded the newer restore image from Microsoft, created a new bootable CD and got the restore app running.

But then the restore app didn’t find the LAN driver. Without a network driver you can’t restore – the network is how the restore app communicates with WHS. On the advice of friends I got the drivers off the latest WHS backup of my laptop as described here. Unfortunately they are 64 bit drivers, and the WHS restore app is a 32 bit app, so the drivers are useless.

Damn!

Some frantic web searching ensued, and finally I stumbled across an article that suggested the 1420P has much the same hardware as the 1410. I had nothing to lose, so I grabbed the Lan_Atheros_1.0.0.19_Vistax64Vistax86_A driver from the Acer support website – this is the LAN driver for the Aspire 1410 – and put it on a USB thumb drive where the WHS restore app could find it.

And that did the trick!! The WHS restore app found the driver, loaded it, and 48 minutes later my tablet was restored to a previous image and it is now working perfectly.

Saturday, March 20, 2010 11:15:40 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, March 18, 2010

I have an app that uses the SL4 RichTextBox control. It is a nice control, and I’ve been enjoying using it. I even went so far as to convert thousands of rows of HTML to Xaml in my database for use with the RTB.

But the control has a couple changes in the new release candidate that I’m having to work around – and if they are not bugs then I’ll have to write a little app to clean the data in my database.

Prior to the RC the minimum value you could set to the Xaml property was “<Section />”. This was (and is) a pain, because it won’t accept null or string.Empty – so if your actual value is null you need to detect that and change it before trying to set the Xaml property.

But in the RC the minimum value is now “<Section xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"/>”. Not a huge change, but it broke my app of course.

The bigger issue is that prior to the RC the RTB allowed the TextDecorations attribute on the <Section> element. And in fact it generated this attribute when it created Xaml.

In the RC the TextDecorations attribute is no longer valid. It isn’t generated, but more importantly it isn’t allowed, so all my Xaml data is invalid.

This is a bit of code that fixes both issues:

string xaml;
if (e.NewValue == null)
  xaml = string.Empty;
else
  xaml = e.NewValue.ToString();
// RTB won't accept an empty string, so if the value is empty/null
// replace it with the minumum necessary Xaml
if (string.IsNullOrWhiteSpace(xaml))
  xaml = "<Section xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"/>";
// RTB used to support TextDecorations, but now doesn't, so that value
// must be removed to avoid a crash
var pos = xaml.IndexOf(" TextDecorations=");
if (pos >= 0)
{
  var closeQuote = xaml.IndexOf("\"", pos);
  closeQuote = xaml.IndexOf("\"", closeQuote + 1);
  xaml = xaml.Remove(pos, closeQuote - pos + 1);
}
return xaml;

In this case e.NewValue is the Xaml text I’m hoping to put into the control, and the xaml field ends up holding the corrected result.

I’m sure other people moving from the beta to the RC will encounter this same issue. I’m rather hopeful that the TextDecorations thing is a bug so I don’t have to fix all my data, but I suspect it is an intentional breaking change…

Thursday, March 18, 2010 7:25:40 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  | 
 Tuesday, March 16, 2010

Hopefully this can save someone some time. I spent a couple hours setting up a virtual machine and installing the Windows Phone 7 dev tools, only to find that the phone emulator won’t run in a virtual machine. It turns out that this is because the emulator is a virtual machine and you can’t run a virtual machine in a virtual machine.

Tuesday, March 16, 2010 10:45:59 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [6]  | 
 Tuesday, March 09, 2010

From Scott Wiltamuth, Product Unit Manager for Visual Studio Languages:

VB and C# Coevolution

Tuesday, March 09, 2010 10:47:11 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, March 04, 2010

MCsla is a prototype that takes SQL Server Modeling (aka “Oslo” and “M”) and CSLA .NET, using them to create an end-to-end story. This story goes like this:

  1. Developer creates a business database for business data
  2. Developer writes concise DSL code
  3. Developer “compiles” DSL code into the SQL Server Modeling repository
  4. End user executes a runtime application, which dynamically creates a UI, business layer and data layer that uses the business database – all this based on the compiled DSL metadata stored in the repository

This saves the developer from a lot of work. In fact the developer writes perhaps 5% of the code they would have written to create the UI, business layer and data layer by hand.

See my discussion of the concepts and prototype in a three part video series:

Exploring SQL Server Modeling through MCsla

You can see the MCsla code in the CSLA .NET repository (web view) or grab it using any svn client from svn://svn.lhotka.net/csla/mcsla/tags/Video1001.

Thursday, March 04, 2010 11:06:23 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [7]  | 
 Monday, March 01, 2010
Monday, March 01, 2010 3:04:57 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

Joost van Schaik spent some time figuring out how to get CSLA .NET 3.8.2 to work with Silverlight 4 – which takes a little effort because SL4 changes the way WCF proxies are referenced in the client config file. It is such an odd change that I rather suspect it might be a bug in SL4, but I guess we’ll see what happens as it gets closer to release.

He also wrote a nice blog post summarizing the steps required, which will probably be useful to a number of people:

.NET by Example: Running CSLALight 3.8.2 under .NET 4 and Silverlight 4

Thank you Joost!

Monday, March 01, 2010 3:01:48 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, February 26, 2010

Continuing on my quest to use the Visual Studio 2010 XAML designer, MVVM and absolutely no code behind, I ran into the common problem of setting focus to a control as a form loads.

This is easily accomplished using code-behind:

firstControl.Focus();

But of course that requires code-behind, which I believe should be unnecessary.

It can also be accomplished by creating an attached property or (with the Blend 3 SDK) trigger action or behavior. Neither of these are great with the VS10 designer though, because the designer has no way to apply attached properties and doesn’t know about the Blend 3 SDK concepts.

So while those solutions are fine, they require manual typing of XAML, which I believe should be unnecessary (as unrealistic as that view might be…).

My solution is to create a FrameworkElement called SetFocus. This shows up in the Toolbox and so can be dragged directly onto the form using the designer. The SetFocus control has no visual aspect, so it doesn’t interfere with the layout or look of the form. Once SetFocus is on the form, the Properties window can be used to set its TargetProperty property, indicating the property that should get focus when the form is loaded.

image

This requires no code-behind and no manual typing of XAML. It keeps the concept of startup focus completely in the view, which (I think) is a good place for it. So my viewmodel doesn’t know or care about this issue. And the same control works in Silverlight and WPF, which should be the goal for any good XAML control.

Here’s the code:

using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace Collective.Controls
{
  /// <summary>
  /// Sets the focus to the TargetControl property as the
  /// form is loaded.
  /// </summary>
  public class SetFocus : FrameworkElement
  {
    /// <summary>
    /// Gets or sets the target UI control.
    /// </summary>
    public static readonly DependencyProperty TargetControlProperty =
      DependencyProperty.Register("TargetControl", typeof(Control),
      typeof(SetFocus), new PropertyMetadata((o, e) =>
      {
        var sf = o as SetFocus;
        if (sf != null && sf.TargetControl != null)
          sf.TargetControl.Focus();
      }));
    /// <summary>
    /// Gets or sets the target UI control.
    /// </summary>
    [Category("Common")]
    public Control TargetControl
    {
      get { return (Control)GetValue(TargetControlProperty); }
      set { SetValue(TargetControlProperty, value); }
    }
  }
}

Friday, February 26, 2010 11:25:09 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [8]  | 
 Friday, February 19, 2010

As noted in a previous post, I’ve been spending some quality time with the new VS10 XAML designer. It is fun, but challenging to figure out how the designer wants everything to work, and to adapt existing CSLA .NET components to work smoothly in the new environment.

Yesterday I spent a substantial amount of time trying to get PropertyStatus, InvokeMethod and Execute to work nicely. These three controls have one thing in common: they all interact directly with the real data object. InvokeMethod and Execute both invoke methods on the data object (usually a viewmodel), and PropertyStatus reads property-specific metadata about a property, such as whether the property has any info/warning/error messages that the user should see.

The VS10 designer uses something called a CollectionViewSource as its primary binding target. When you drag-and-drop a type from the Data Sources window onto your form, the designer creates a CVS resource in the form and uses that as the DataContext for your UI elements. In this regard it is not entirely unlike a data provider control in WPF, though it is certainly not a data provider control.

If you are using a viewmodel (and I am), then your DataContext is actually a hierarchy of object instances.

image

This is made slightly more complex when you realize that the Source property of a CollectionViewSource can only be a list. So really the CVS contains a list of viewmodel objects – but in my case that list has only one item.

InvokeMethod and Execute both need access to the viewmodel – that’s the object containing the methods to be invoked. PropertyStatus actually needs access to the Model (the real business object), because that’s the object where the business properties and associated metadata are actually implemented.

None of this would be that complex, except that the VS10 designer sets the DataContext to the CVS, and then uses currency to make one item in the Source property “current”. But if you, in code, get access to the DataContext for a control you get the CVS. If you get a BindingExpression object for a given binding, the DataItem is the current item in the CVS, which turns out to not be the viewmodel. Instead the DataItem on a binding is an internal type within .NET.

And this is what had me stuck. The CVS has no CurrentItem property, but this internal type does. However (short of reflection), there’s no way to interact with members of an internal type. What to do? Thanks to help from Mark Boulter I now know that this internal type implements the public ICollectionView interface, and that interface does have a CurrentItem property.

Whew!

What this means is that in InvokeMethod and Execute, I can take the associated UI control (like a Button or something) and use it to find the viewmodel:

public static object GetTarget(UIElement ctrl)
{
  object result = null;
  result = ctrl.GetValue(TargetProperty);
  if (result == null)
  {
    var fe = ctrl as FrameworkElement;
    if (fe != null)
      result = fe.DataContext;
  }
  var icv = result as ICollectionView;
  if (icv != null)
    result = icv.CurrentItem;
  return result;
}

This basically takes the DataContext value, sees if it is an ICollectionView, and if so it returns the CurrentItem – which is the real data object, or at least the viewmodel.

PropertyStatus is a little more complex, because it has to trace down to the actual underlying business object, and if so it needs to dereference elements of the property name path. For example, the property name might be Name, or it might be Model.Name. If it is Name, the assumption is that CurrentItem is the actual data object. If it is something like Model.Name, the assumption is that PropertyStatus needs to use the Name property on the object referenced by the Model property. The code actually goes n levels like this, allowing for access deep into hierarchical object graphs.

private object GetRealSource(object source, string bindingPath)
{
  var icv = source as ICollectionView;
  if (icv != null)
    source = icv.CurrentItem;
  if (source != null && bindingPath.IndexOf('.') > 0)
  {
    var firstProperty = bindingPath.Substring(0, bindingPath.IndexOf('.'));
    var p = MethodCaller.GetProperty(source.GetType(), firstProperty);
    return GetRealSource(
      MethodCaller.GetPropertyValue(source, p),
      bindingPath.Substring(bindingPath.IndexOf('.') + 1));
  }
  else
    return source;
}

Again, if the source is an ICollectionView, the code skips right to the CurrentItem property, which is the first “real” object worth using.

I suppose writing controls that interact with the real data object isn’t something people do every day, but if you end up writing such a control hopefully this blog post will help save you some time and frustration.

Friday, February 19, 2010 2:42:23 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |