To answer my own question, yes this is possible.
Firstly, add your own layer with a custom tile source:
<m:Map>
    <m:Map.Mode>
     <mCore:MercatorMode/>
    </m:Map.Mode>
    <m:Map.Children>
     <m:MapTileLayer>
      <m:MapTileLayer.TileSources>
       <local:CustomTileSource/>
      </m:MapTileLayer.TileSources>
     </m:MapTileLayer>
    </m:Map.Children>
</m:Map>
Next, define the CustomTileSource. Here is an example:
public class CustomTileSource : TileSource
{
 public CustomTileSource()
  : base(GetAbsoluteUrl("/ClientBin/Resources/{0}.png"))
 {
 }
 public override Uri GetUri(int x, int y, int zoomLevel)
 {
  var quadKey = new QuadKey(x, y, zoomLevel);
  return new Uri(String.Format(this.UriFormat, quadKey.Key));
 }
 public static string GetAbsoluteUrl(string strRelativePath)
 {
  if (string.IsNullOrEmpty(strRelativePath))
   return strRelativePath;
  string strFullUrl;
  if (strRelativePath.StartsWith("http:", StringComparison.OrdinalIgnoreCase)
    || strRelativePath.StartsWith("https:", StringComparison.OrdinalIgnoreCase)
    || strRelativePath.StartsWith("file:", StringComparison.OrdinalIgnoreCase)
    )
  {
   //already absolute
   strFullUrl = strRelativePath;
  }
  else
  {
   //relative, need to convert to absolute
   strFullUrl = System.Windows.Application.Current.Host.Source.AbsoluteUri;
   if (strFullUrl.IndexOf("/ClientBin") > 0)
    strFullUrl = strFullUrl.Substring(0, strFullUrl.IndexOf("/ClientBin")) + strRelativePath;
  }
  return strFullUrl;
 }
}
Note how the tile source must return a URL. If you have an image you want to use as the map, you can use the MapCruncher tool to prepare it.
HTH,
Kent