/// <summary>
        /// Bookkeeping for unregistering IDataSourceRenderer.
        /// </summary>
        /// <param name="idsr">Instance to unregister.</param>
        protected void Unregister(IDataSourceRenderer idsr)
        {
            var source = DataSources.Cast <DataSource>().SingleOrDefault <DataSource>((dds) => dds.Name == idsr.DataSourceName);

            if (source != null)
            {
                source.Unregister(idsr);
            }
        }
 /// <summary>
 /// Determine what kind of render is required, and run it.
 /// If anything is dirty, full layout, else adjust transforms.
 /// Once all components are "clean" only the visual transforms are updated; no data traversal is done.
 /// </summary>
 /// <param name="ls">The current layout state.</param>
 protected void RenderComponents(LayoutState ls)
 {
     _trace.Verbose($"render-components {ls.Dimensions.Width}x{ls.Dimensions.Height}");
     if (ls.Dimensions.Width == 0 || ls.Dimensions.Height == 0)
     {
         return;
     }
     if (DataSources.Cast <DataSource>().Any((ds) => ds.IsDirty))
     {
         FullLayout(ls);
     }
     else
     {
         TransformsLayout(ls);
     }
 }