Cider Item Creation


In Windows Forms, there were many occasions when you wanted to separate out your design time code from your runtime code.  For design time code you didn’t want to execute at runtime, you would use a designer and for runtime code you didn’t want to execute at design time (i.e. it did a bunch of database access) in most situations you could use the Control.DesignMode property.


The problem with Control.DesignMode was that it depended on IComponent.Site being set for your control.  Unfortunately, there were cases when this wasn’t true, most noteably in the constructor of that control.


If you’ve seen Brian Pepin’s articles on the Cider designer (part 1 here and part 2 here) you’ll know that in Cider, we’ve gone away from IComponent.  This means that there isn’t a Control.DesignMode property for WPF/Avalon controls.


Instead, Cider’s Extension architecture (again see Brian’s articles) is used to add a CustomInstanceFactory to a control.  When Cider goes to instantiate that control, instead of calling “new” or “Activator.CreateInstance” it calls its CustomInstanceFactory instead.


For example:


[Extension(typeof(SliderAdornerInstanceFactory))]
public class SliderAdornedButton : Button
{
      private bool IsDesignMode = false;


      public bool SetIsDesignMode
      {
            
get { return this.IsDesignMode; }
            
set { this.IsDesignMode = value; }
      }
}


class SliderAdornerInstanceFactory : CustomInstanceFactory
{


      public override object CreateInstance(Type type, params object[] arguments)
      
{
            
object instance = base.CreateInstance(type, arguments);
            
SliderAdornedButton sab = instance as SliderAdornedButton;


            if (sab != null) sab.SetIsDesignMode = true;
            
return instance; 
      
}
}


In other words, at design time, if there is a Custom Instance Factory attached to an object, it is used to instantiate the object instead of the designer itself.  This extensibility point allows you to set a bool indicating that you are in design mode (as the sample code above shows) and do any other design time specific code.


In fact, you could even return a design time specific instance of your control.  As an example, Cider currently uses this mechanism to provide our own design time version of Window since we can’t use a real Window instance as it cannot be parented to another control.


To summarize: Custom Instance Factories provide the ability to hook into the creation of your control at design time.


Comments (5)

  1. jfo's coding says:

    Brian walks through the history of the implementation of grab handles and snaplines in the designer,…

  2. One more addition to CIDER bloggers. James Nakashima – PM on the CIDER team. He has some great posts…

  3. Shawn Chen says:

    I am wondering if this class CustomInstanceFactory is internal used only? I cannot find it in WPF and Cider assemblies.

    If it is an internal class, how can I be notified when my control is instantiated by Cider?

  4. jnak says:

    Hi Shawn,

    You asked this and other questions in a forum post: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=600484&SiteID=1&mode=1  

    Wanted to let you know that your questions have been answered.