我使用Visual Studio 2008在winforms C#中实现了一个大表单。 在对话的大部分工作正常后,当我尝试打开设计器时,它开始显示很多错误masseges。
“变量未声明或从未分配”
我得到了很多以前运行良好的控件。 我认为使用
的自定义控件会发生这种情况答案 0 :(得分:6)
第一个建议不使用构造函数形式的任何复杂逻辑,但是在表单的加载事件(或OnLoad的覆盖)法)。
设计者使用构造函数的代码来显示表单,如果您有错误,您的表单将在VS设计器中“无法显示”。
其次,每次在设计器中遇到问题时,请关闭它并重建表单的项目。验证错误列表窗口中的错误和警告。修复后,在设计模式下重新打开表单。
答案 1 :(得分:4)
我找到了一个有效的解决方案:
当我的自定义控件和对话框位于同一个DLL /项目/程序集中时,会出现初始问题。
我为所有自定义控件创建了一个独立的Windows控件DLL,并且...设计器显示了对话框。
答案 2 :(得分:3)
我相信我已经看到了同样的问题,我认为这是VS中的一个错误。偶尔(我不确定具体情况),即使创建一个全新的空表单并添加一个自定义控件也会导致设计师以您描述的方式爆炸。将自定义控件的代码复制并粘贴到一个全新的空项目中并将其添加到新表单中,该问题不会出现。
设计师不会在InitializeComponent()
顶部附近生成线:
this.customControl1 = new Controls.CustomControl();
事实上,如果我手动插入上面的行,那么在重建项目时会删除它。
回顾我以前的项目,我可以看到VS2005中存在这个错误,我今天仍然在VS2010中得到它。我之前的代码充满了这样的内容:
public MyForm()
{
// HACK: work around VS bug
this.customControl1 = new Controls.CustomControl();
InitializeComponent();
}
毋庸置疑,设计师大部分时间都在工作。我没有找到任何方法来一致地重现问题,但有趣地从解决方案中删除一个表单并重新创建一个具有相同名称+自定义控件的表单,问题仍然存在。
答案 3 :(得分:2)
我们的某个表单也出现了此错误,我们很难诊断导致它的原因。表单代码实际上是3x .cs文件。基本form.cs,designer.cs和表单被扩展(它被声明为部分类)。
所以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
}
}
这个案例的问题是设计器中的变量的变量声明必须出现在.designer.cs文件中,而不是出现在任何其他源文件中 EM>。因此,当它说变量未声明时,它意味着它在设计师寻找的范围内未声明。
似乎有人决定将变量声明移动到其他部分类文件中,并没有意识到这会破坏设计师。
答案 4 :(得分:1)
正如其他人所说,你不应该在用户控件的构造函数中有任何复杂的逻辑。
理论上,进行任何复杂初始化的地方应该是Load事件处理程序或OnLoad()。但是,在VS2010中,使用控件的Load事件(或OnLoad())是不够的。
如果您的UserControl与使用它的表单位于同一个程序集中,并且您想要在Designer中查看表单,VS2010不仅会执行UserControl的构造函数,还会执行其OnLoad()或Load事件。这似乎并不总是发生,但是当Designer需要重建表单时。
因此,如果您有任何复杂的逻辑或使用外部资源(如数据库),则在打开封闭表单的Designer时可能会抛出此错误。 这很糟糕,因为使用Load事件应该是正确的地方。
您可能必须对运行表单之前必须初始化的任何重要资源使用延迟初始化。
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;
}
}
答案 5 :(得分:0)
检查您的designer.cs文件。它可能缺少控制声明。
您的代码是否构建并运行?
答案 6 :(得分:0)
这是IDE中的一个错误。无论你如何看待它,构造函数都会以不确定的方式实例化你的字段,然后在构造函数中将它们用作静态。
例如:
private ComponentResourceManger resources = null;
private void InitializeComponent() {
resources = new ComponentResourceManager(typeof(MainForm));
...
}
通常 会破坏您的设计师。有时它会起作用,但通常会让人感到困惑。可能会重命名所有嵌入的资源甚至删除它们。在.resx文件中有一个图像副本是有意义的,但设计者喜欢看到每个控件都有一个。即使它被共享..它也喜欢制作副本。
典型错误包括“无法找到'MainForm'”以及稍后向下...获取一些NPE for resources.GetObject(“MyImage”);即使.resx指定了 完全 文件名。
如果您在InitializeComponent()例程中实例化obj,通常可以保证解决方法正常工作。
private void InitializeComponent() {
ComponentResourceManager resources = new ComponentResourceManager(typeof(MainForm));
...
}
您将如何在外部引用此内容取决于您。
答案 7 :(得分:0)
在我的情况下取决于我为之构建项目的平台。对于x86,一切都是正确的,但对于x64,我收到了这个错误。所以,我的解决方案是在Debug / x86下开发项目,然后为所有必需的目标平台构建它。