可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I implement a big form in winforms C# with Visual Studio 2008.
after working fine for a big portion of the dialog it start showing a lot of error masseges as in the title when I try to open the designer.
"The variable is either undeclared or was never assigned"
I got this for a lot of controls that worked fine before.
I think it happens with custom control that I use
回答1:
First recommendation is do not use any complicated logic in the form constructor, but in the form's Load event(or overrides of the OnLoad method).
The designer uses the code of constructor to display the form, and if you have errors your form will be "undisplayable" in the VS designer.
Secondly, every time you have problems in the designer, close it and rebuild your form's project. Verify the errors and warnings in the error list Window. After fixing it, reopen your form in desig mode.
回答2:
I found a working solution:
The initial problem happened when my custom controls and the dialog were in the same DLL/project/assembly.
I created a separated Windows control DLL for all the custom control and ... the designer showed the dialog.
回答3:
I believe I have seen the same issue and I think it is a bug in VS. Now and then (I'm not sure of the exact circumstances), even creating a completely new and empty form and adding a single custom control will cause the designer to blow up in the way you describe. Copying and pasting the code for the custom control into a brand new empty project and adding it to a new form, the issue doesn't appear.
The designer just doesn't generate the line near the top of InitializeComponent()
:
this.customControl1 = new Controls.CustomControl();
In fact, if I manually insert the line above it is removed when the project is rebuilt.
Looking back at my previous projects, I can see the bug was present in VS2005 and I still get it today in VS2010. My previous code is peppered with bits like this:
public MyForm()
{
// HACK: work around VS bug
this.customControl1 = new Controls.CustomControl();
InitializeComponent();
}
Needless to say, the designer works most of the time. I've not found any way of consistently reproducing the problem, but interestingly removing a form from the solution and recreating one with the same name + custom control, the problem is still there.
回答4:
This error also occurred for one of our forms and we had a really difficult time diagnosing what was causing it. The form code was actually in 3x .cs files. The base form.cs, the designer.cs and the form was extended (it was declared as a partial class).
So MyForm.cs:
namespace MyNamespace
{
public partial class MyForm : Form
{
// Some variable declarations
// Some method declarations
}
}
MyForm.designer.cs:
namespace MyNamespace
{
partial class MyForm
{
#region Auto Generated
protected override void Dispose(bool disposing)
{
// Generated dispose code here
}
private void InitializeComponent()
{
// Generated designer code here
// Error 'The variable <variable name> is either undeclared or was never assigned' points to one of the lines in here.
}
#endregion
}
}
MyForm.Extended.cs:
namespace MyNamespace
{
public partial class MyForm
{
// Some variable declarations
// Some method declarations
}
}
What the issue was for this case was the variable declarations for variables in the designer InitializeComponent must occur in the .designer.cs file and not in any of the other source files. So when it said the variable is either undeclared it meant it was undeclared in the scope the designer was looking for it.
It seems someone decided to move variable declarations into one of the other partial class files and didn't realise that breaks the designer.
回答5:
As others have said, you should not have any complicated logic in the constructor of the user control.
In theory, the place to do any complicated initialisations should be the Load event handler or OnLoad(). However, in VS2010, using the Load event of the control (or OnLoad()) is not enough.
If your UserControl is residing in the same assembly as the form that is using it, and you want to view the form in the Designer, VS2010 does not only execute the constructor of the UserControl, but also its OnLoad() or Load event. This does not seem to happen always, but when the Designer needs to rebuild the form.
So if you have any complicated logic there or use external resources, like a database, it may throw this error when opening the Designer for the enclosing form.
This is bad because using the Load event should be the right place to do it.
You might have to use lazy initialisation for any vital resources you have to initialise before running the form.
E.g.:
public class MyUserControl: UserControl
{
...
private List<MyObject> myObjects = null;
private List<MyObject> MyObjects
{
get
{
if (myObjects == null)
{
// lazy initialisation here
using (var dbContext = new MyVerySpecialDatabaseContext())
{
myObjects = dbContext.MyObjects.ToList();
}
}
return myObjects;
}
}
public MyUserControl()
{
InitializeComponent();
this.Load += new System.EventHandler(this.MyUserControl_Load);
... // more UI initialization, but no complicated logic here
}
private void MyUserControl_Load(object sender, EventArgs e)
{
this.myDataBindingSource.DataSource = MyObjects;
}
}
回答6:
Check your designer.cs file. It may be missing control declarations.
Does your code build and run?
回答7:
It is a bug in the IDE. No matter how you look at it, there is an undeterminstic way the constructor will instantiate your fields and have them be used as static later down in the constructor.
For example:
private ComponentResourceManger resources = null;
private void InitializeComponent() {
resources = new ComponentResourceManager(typeof(MainForm));
...
}
Will usually break your designer. Sometimes it works, but normally it gets confused.. may rename all your embedded resources or even remove them. It makes sense to have one copy of an image in your .resx file, but the designer likes to see one for every control. Even if it was shared .. it likes to make a copy.
Typical errors include, "Unable to find 'MainForm'" and later down .. get some NPE for resources.GetObject("MyImage"); Even if the .resx has it with the exact filename specified.
The workaround is usually always guaranteed to work if you instanciate the obj within the InitializeComponent() routine.
private void InitializeComponent() {
ComponentResourceManager resources = new ComponentResourceManager(typeof(MainForm));
...
}
How you will reference this externally is up to you.
回答8:
In my case in depends on the platform I build the project for. For x86 everything was right, but for x64 I received this error. So, my solution was to develop the project under Debug/x86 and then build it for all required target platforms.