in
Forums
Blogs
Files
Devexpress.Com
Client Center
Support Center
DevExpress Channel

Custom user control, default session and Visual Studio Win Forms designer

Last post 10/21/2008 10:42 AM by Ondrej Bohaciak. 0 replies.
Page 1 of 1 (1 items)
Sort Posts:
Previous Next
  • 10/21/2008 10:42 AM

    Custom user control, default session and Visual Studio Win Forms designer

    (I have spent some time figuring this one myself, so I hope it will be of use to someone...)

    When creating a UserControl, doesn't matter if it's System.Windows.Forms.UserControl or DevExpress.XtraEditors.XtraUserControl a problem occurs when a data source (XPView, XPCollection, UnitOfWork or anything else that requires a session) is placed on a control and then the control is used in a form

    The problem boils down to:


    1. Data sources use a session, which, if not set, will be set to default (Session.DefaultSession).

    2. Sessions in your app are created at runtime (at login or on-the-fly)

    3. Finished UserControl when placed on a form is not in design mode -> Visual Studio Win Forms designer actively executes constructor and event handling routines of child controls


    This will cause an exception when adding control to the form or designer will issue warning. The warning message is typically something along the lines of "C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\DefaultDomain.mdb" 
    cannot be found or is inaccessible
    . This is the Access database used by default session.

    As a solution, you can reimplement the DesignMode property and distinguish between code running in the designer or at runtime. 
    Base implementation of DesignMode cannot really be used to determine this. The recommended method is to check whether code being run is executed in VS, that means checking if the current process is "devenv.exe".


    public new bool DesignMode
    {
        get
        {
            // check base implementation as well
            return ((base.DesignMode) || 
                        (Process.GetCurrentProcess().ProcessName.ToLowerInvariant() == "devenv"));
        }
    }  

    (There are other methods as well, such as checking the licensing mode which is VS specific, but I prefer this one)

    It is then possible to rip out the code from InitializeComponent which instantiates and initializes data sources and place it behind a conditional, which will only be run if the control is outside the VS designer.

    internal class Order : XPObject
    {
        ...

        public Order(int someArg)
        {
            InitializeComponent();
       
            if (!this.DesignMode)
            {
                // xpCollection1 init
                this.xpCollection1 = new UnisComp.Pry.Spol.Base.BL.BusinessCollectionBase();
                ((System.ComponentModel.ISupportInitialize)(this.xpCollection1)).BeginInit();
                this.xpCollection1.LoadingEnabled = false;
                this.xpCollection1.ObjectType = typeof(Category);
                ((System.ComponentModel.ISupportInitialize)(this.xpCollection1)).EndInit();  
            }
        }

        ...

    }

    Things to consider:


    1. VS designer is runtime. It will execute code for child controls and I mean any method which is in constructor call chain or any event handler that reacts to events which are raised by the designer. The parent form or control which is being designed is merely serialized so no problem there.
    2. Events raised by the designer include control's Load event, so that's no place for initialization either.
    3. This behaviour is by design and will not be changed. Developers are encouraged to work around this 
      (see Bug Report Details: DefaultDomain.mdb (DevExpress), Bug Report Details: Form can't be open in the designer and throws an exception about DefaultDomain.mdb (DevExpress) and DesignMode property not telling the full truth (.NET)


Page 1 of 1 (1 items)
Copyright © 1998-2008 Developer Express Inc.
ALL RIGHTS RESERVED