October, 2006

  • Cloudy in Seattle

    Detecting Design Mode

    • 11 Comments

    A while back, Brian posted an article about how we proposed to implement the equivalent to the Windows Forms Control.DesignMode property in Cider.

    In his follow up article, he talks about how we dropped the original proposal and worked with the WPF team to get a the new DesignerProperties class into WPF's PresentationFramework assembly.  This change was driven by the feedback he got on his blog -- your feedback makes a difference.

    So instead of looking up a DependencyProperty through the AppDomain data context by name, you can check the DependencyProperty defined in the DesignerProperties class.  A far better solution that both Cider and Sparkle will support.

    When the designer starts up, it will change the default value of the IsInDesignMode attached property from false to true by overriding its metadata.  For parts of the designer like the Property Browser or adorner layer that will host controls in a runtime context (as part of the design time UI), the IsInDesignMode property will be set to false on those visual trees.

    What that means is that whenever a control is created, it will be able to check whether or not it is in design mode and get back a value of true if that control was created by the designer.  This will, for the most part, be the correct and final value, unless that control is hosted in the Property Browser or Adorner context where the IsInDesignMode property will switch from true to false for that control when it is parented to its final visual tree.

    Getting the IsInDesignMode Property

    Here is a simple example of making a runtime versus design time decision using the DesignerProperties class:

        public class CustomButton : Button
        {
            public CustomButton()
            {
                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    Content = "In Design Mode";
                }
                else
                {
                    Content = "Runtime";
                }
            }
        }

    Note how this code can be run from the constructor.

    Setting the IsInDesignMode Property

    Isn't setting the IsInDesignMode property the responsiblity of the designer?  In most cases, yes... but not all cases. 

    Consider the situation where a control has design time adorners that popup a dialog when clicked.  Since the dialog is not in the visual tree of the adorner layer, it will get the default value of the IsInDesignMode property which is set to true when the designer starts up. 

    In this case, the control developer will want to set the IsInDesignMode property to false for that dialog so that the controls on that dialog operate in a runtime context.

    The DesignerProperties class has a SetIsInDesignMode property to accommodate this kind of scenario:

    System.ComponentModel.DesignerProperties.SetIsInDesignMode(element, newValue);

    Tracking Changes to the IsInDesignMode Property

    It is important to track changes to the IsInDesignMode property as its initial value may not be its final value -- the Property Browser Editor or Adorner Layer example mentioned above.

    For example, the value of the IsInDesignMode property when your custom control is instantiated by Cider will almost always be true.

    If that control is being used within the Cider Property Browser in an Extended Editor you've written, it will change to false when that control is added into the Property Browsers visual tree where the IsInDesignMode property is false.

    To track state changes of the IsInDesignMode property, override OnPropertyChanged.

Page 1 of 1 (1 items)