April 29, 2012

Page Breaks in HTML

Page break after description

Fixing page breaks just after a title when printing HTML.
Used an XSLT transform to break my document into sections each with a title. Trouble is when printing HTML, there is no way to know where the page break will be placed. In my case I ended up with page breaks just after a section title!. Fixed this by putting a <br style="page-break-after:always"/> at the end of each section. There are other types of page break in CSS but this fixed the problem and quickly. Some browsers do not accept all forms of page break; Firefox, for example.

April 24, 2012

Non-Virtual Interface Design Pattern

The Non-Virtual Interface Design Pattern is described here: http://www.blackwasp.co.uk/NVI.aspx

Basically the pattern promotes the use of non-virtual public base class methods that can be used by clients. A set of overridable behaviours are exposed (as protected or protected internal) that are invoked directly by exposed public methods in the base class. This way the base class behaviour can be overriden by deriving classes.

April 19, 2012

File Drag and Drop in WPF

Watch drag and drop to text boxes as they need special handling see Textbox Drag/Drop in WPF

Add to your control (or main window) declaration
AllowDrop="True" DragEnter="Window_DragEnter" Drop="Window_Drop"

In the code do something like this (this is a file drag/drop sample):
#region DragDrop

bool IsValidDropData(IDataObject draggedObj)
{
  bool res = false;
  IEnumerable<string> lst = draggedObj.GetData(DataFormats.FileDrop)
     as IEnumerable<string>;
  if (lst != null)
  { 
    // In this sample I am only taking the first file
 // the rest are ignored
    string first = lst.FirstOrDefault();
    if (!string.IsNullOrWhiteSpace(first))
    {
      FileInfo fi = new FileInfo(first);
      res = fi.Exists && HasValidFileExtension(fi);
    }
  }
  return res;
}

private bool HasValidFileExtension(FileInfo file)
{
  string[] validExtensions = new[] { ".xml" };

  bool res = false;
  res = (file != null) && validExtensions.Contains(file.Extension);
  return res;
}

private void Window_DragEnter(object sender, DragEventArgs e)
{
  if (IsValidDropData(e.Data))
  {
    e.Effects = DragDropEffects.Copy;
  }
  else
  {
    e.Effects = DragDropEffects.None;
  }
}

private void Window_Drop(object sender, DragEventArgs e)
{
  if (IsValidDropData(e.Data))
  {
    IEnumerable<string> files = e.Data.GetData(DataFormats.FileDrop)
        as IEnumerable<string>;
    string fileName = files.FirstOrDefault();
    if (!string.IsNullOrEmpty(fileName) && 
     File.Exists(fileName))
    {
       DoSomethingWith(fileName);
    }
  }
}

#endregion DragDrop

Embedded Resources

To embed a resource:
  1. Add it to the project
  2. Change the build action to "Embedded Resource"
The compiler adds the root namespace of the project to the name of the resource when it is included in the project. For example, if the root namespace of your project is MyNamespace, and the resource is XXX.xslt then the name of the resource when retrieving it is MyNamespace.XXX.xslt.

Further, if the resource is placed in a project folder, the name of the folder is added into the resource name. For example, if the embeded resource XXX.xslt, exampled above, is placed in a project folder "Resources" then the resource name when retrieving it is now MyNamespace.Resources.XXX.xslt.

To retrieve a resource thus embedded use the method GetManifestResourceStream on the assembly object. For example to retrieve the embedded resource MyNamespace.Resources.XXX.xslt from the executing assembly:
private string RetrieveEmbeddedStringResource(string resourceName)
{
  Assembly myAssembly = Assembly.GetExecutingAssembly();
  Stream fileStream = myAssembly.GetManifestResourceStream(resourceName);
  string text = "";
  if (fileStream != null)
  {
    using (StreamReader streamReader = new StreamReader(fileStream))
    {
      text = streamReader.ReadToEnd();
    }
  }
  return text;
}
and to call it:
string xslt = RetrieveEmbeddedStringResource(
    "ViewNUnitTestResults.Resources.NUnitTestResultsToHtml.xsl");
In this case the namespace is ViewNUnitTestResults, the resource is NUnitTestResultsToHtml.xsl which is stored under the project subdirectory Resources.
To retrieve a binary embedded resource:
private byte[] RetrieveByteArrayEmbeddedResource(string resourceName)
{
    byte[] bytes = new byte[0];
    Assembly myAssembly = Assembly.GetExecutingAssembly();
    bool resFound = myAssembly.GetManifestResourceNames().Contains(resourceName);
    if (!resFound)
        throw new ArgumentException("Could not find the embeded resource \'" +
            resourceName + "\'");
    using (Stream stream = myAssembly.GetManifestResourceStream(resourceName))
    {
        bytes = new byte[stream.Length];
        stream.Read(bytes, 0, (int)stream.Length);
    }
    return bytes;
}
and it is called like this
byte[] bytes = RetrieveByteArrayEmbeddedResource("XXXTests.Something.bin");