トップ回答者

Windows Designer Bug when using ConnectionString in user control.

質問

When adding a user control to a Windows Form, the designer throws the following error.

"The ConnectionString property has not been initialized."

The control in question contains a DateTimePicker control that reads its value from the database. The control works properly at runtime. It's just that the designer cannot resolve the connection string at design time and is preventing me from manipulating the control once one the form.

Ignoring the error just loads the form without the control in the designer view. This is not helpful.

回答

First of all, where is the connection string placed? I suppose it is in a configuration file correct? Possibly App.config...

Well, when you retrieve a connection string that is located in the configuration of the application, say through the ConfigurationManager, this configuration file must reside in the same CodeBase of the Assembly being "executed". And guess what:

When Visual Studio design-time magic begins, every time you drag and drop one of your User controls from the toolbox onto the designer surface, the current IDesignerHost of the IDesigner (or IRootDesigner) attached to your type is actually instantiating your User control type in its CreateComponent(Type) method. In short: this really means that the code (the very binaries, exe or dll's) are being loaded by the CLR upon Visual Studio request (in order to create you controls.) Visual Studio copies these binary files to a private, temporary folder in the Local Settings\Application Data\Microsoft\VisualStudio\ folder of the current user profile. But Visual Studio knows NOTHING about the possible configuration file that might be required for the control library (specially if it's a DLL, since there is no DLL configuration file architecture starndard in .NET -- there is an Application configuration architecture, but not a DLL configuration.) In any case, EXE or DLL, this config file is NOT copied to this temporary location.

If during initialization of your User control, you are directly or indirectly depending on retrieving any information stored in the configuration of the application, say by binding to a data source from a database, for which you have stored the connection string the App.config file. It will obviously work at runtime (assuming the programmer is competent enough) but at design time, this config file does not get copied to the appropriate location by VS, and unless you place your connection string (or any other appSettings) in the machine configuration file, the returned connection string will be empty.

Try the following hint to help you see what I mean:

Inside the contructor of your User control, and after the call to the InitializeComponent() method:

Compile, and then drag and drop an instance of this User control type. You will see a message box with the crazy path of the executing assembly, which basically is one the ones you are building.

Damiano: The way that you propose obviously makes sense, as you are aborting any possible error at contruction. That might be perfectly acceptable at desing time, but it didn't explain the underlying factor behind the problem.

Oh, and by the way, it is NOT a bug of the Windows Forms Designer... (although, I could agree with you if what you are blaming is Visual Studio itself...)

First of all, where is the connection string placed? I suppose it is in a configuration file correct? Possibly App.config...

Well, when you retrieve a connection string that is located in the configuration of the application, say through the ConfigurationManager, this configuration file must reside in the same CodeBase of the Assembly being "executed". And guess what:

When Visual Studio design-time magic begins, every time you drag and drop one of your User controls from the toolbox onto the designer surface, the current IDesignerHost of the IDesigner (or IRootDesigner) attached to your type is actually instantiating your User control type in its CreateComponent(Type) method. In short: this really means that the code (the very binaries, exe or dll's) are being loaded by the CLR upon Visual Studio request (in order to create you controls.) Visual Studio copies these binary files to a private, temporary folder in the Local Settings\Application Data\Microsoft\VisualStudio\ folder of the current user profile. But Visual Studio knows NOTHING about the possible configuration file that might be required for the control library (specially if it's a DLL, since there is no DLL configuration file architecture starndard in .NET -- there is an Application configuration architecture, but not a DLL configuration.) In any case, EXE or DLL, this config file is NOT copied to this temporary location.

If during initialization of your User control, you are directly or indirectly depending on retrieving any information stored in the configuration of the application, say by binding to a data source from a database, for which you have stored the connection string the App.config file. It will obviously work at runtime (assuming the programmer is competent enough) but at design time, this config file does not get copied to the appropriate location by VS, and unless you place your connection string (or any other appSettings) in the machine configuration file, the returned connection string will be empty.

Try the following hint to help you see what I mean:

Inside the contructor of your User control, and after the call to the InitializeComponent() method:

Compile, and then drag and drop an instance of this User control type. You will see a message box with the crazy path of the executing assembly, which basically is one the ones you are building.

Damiano: The way that you propose obviously makes sense, as you are aborting any possible error at contruction. That might be perfectly acceptable at desing time, but it didn't explain the underlying factor behind the problem.

Oh, and by the way, it is NOT a bug of the Windows Forms Designer... (although, I could agree with you if what you are blaming is Visual Studio itself...)