编译期间显示的用户控制错误消息
User Control error message displayed during Compile
我在 Visual Studio 2019 年创建了一个 C# 用户控件。它有一个名为 "BoundLayout" 的 属性。
public Layout BoundLayout
{
get
{
return _Layout;
}
set
{
_Layout = value as Layout;
if (_Layout == null)
{
MessageBox.Show("Value submitted is not of type 'LAYOUT'","Invalid Value",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
InitializeControl();
}
}
}
如果程序试图将不兼容的值分配给 属性,则会在 MessageBox 中显示一条错误消息。这工作正常。
非常奇怪的是,每当我构建(不是 运行)项目时,此错误消息都会显示在其模态 MessageBox 中,必须先确认,然后才能 return 到 Visual Studio.在调试和发布模式下构建时会发生这种情况。添加到 属性 集代码的断点不会被触发。构建成功完成,没有错误或警告,我可以 运行 应用程序。
包括此用户控件在内的应用程序按预期运行。我以前从未遇到过这种行为。还有其他人吗?
用户控件的完整(仍在开发中)代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Dispatcher
{
public partial class DivisionModuleGrid : UserControl
{
private Layout _Layout = null;
private ObservableListSource<LayoutDivision> _LayoutDivisions;
private DivisionModulesList _activeDivision = null;
private int _divisionCount;
public Layout BoundLayout
{
get
{
return _Layout;
}
set
{
_Layout = value as Layout;
if (_Layout == null)
{
MessageBox.Show("Value submitted is not of type 'LAYOUT'","Invalid Value",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
InitializeControl();
}
}
}
public DivisionModulesList ActiveDivision
{
get
{
return _activeDivision;
}
set
{
_activeDivision = value as DivisionModulesList;
if (_activeDivision != null)
{
lbl_ActiveDivision.Text = _activeDivision.DivisionName;
}
else
{
lbl_ActiveDivision.Text = "-No Active Division-";
}
}
}
public DivisionModuleGrid()
{
InitializeComponent();
}
private void InitializeControl()
{
_LayoutDivisions = _Layout.LayoutDivisions;
_divisionCount = _LayoutDivisions.Count;
tbx_LayoutName.Text = _Layout.LayoutName;
// Grid Layout divide into Rows & Columns
int tlp_rows = _divisionCount / 3;
TableLayoutPanel tlp = (TableLayoutPanel)(Controls.Find("tlp_DivisionGrid", false)[0]);
DivisionModulesList dml;
foreach (LayoutDivision ld in _LayoutDivisions)
{
dml = new DivisionModulesList(ld);
dml.BoundDivision = ld;
tlp.Controls.Add(dml);
}
}
private void Tlp_DivisionGrid_Paint(object sender, PaintEventArgs e)
{
}
}
}
在为 UserControl 创建您自己的属性时,如果您在另一个地方使用此 UserControl,Designer 会为此 属性 生成代码,例如:
yourControl.BoundLayout = null;
在Designer.cs文件中搜索;直到重新生成代码才会解决问题
如果设计器显示您的控件,它会运行您的代码,并在设计时(不是生成时或运行时)显示您的 MessageBox。
永远避免这种情况
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
public Layout BoundLayout
在您的所有属性上,如果您打算仅通过代码而不是在设计器中对其进行修改,尤其是当 null 是无效值时。
当在另一个地方再次使用您的 UserControl 时,它不会再创建此 BoundLayout=null,但是对于您的 UserControl 的现有引用,您必须手动删除此行。
一般建议:一般来说,您应该抛出异常而不是显示 MessageBox。但这与问题无关。
您已将 属性 的初始值定义为 null。这意味着,当您在窗体上放置一个控件实例时,它也会序列化空赋值并生成如下代码:
userControl1.Name = "userControl1";
userControl1.Size = new Size( 100, 100);
userControl1.SomeProperty = null;
...
要解决此问题,您可以使用以下任一选项:
- 防止设计器序列化为 null 的值。
- 在设计时禁用验证。
- 防止设计器始终序列化该值。 (同样由 Holger 提出)
示例 1 - 防止设计器序列化值为 null 的值
您可以使用 DefaultValue
属性将 属性 的默认值设置为 null。然后,当您将控件放在窗体上或在设计时将空值分配给 属性 时,当 属性 的值为 null 时,它不会被设计器序列化。
private SomeType someProperty = null;
[DefaultValue(null)]
public SomeType SomeProperty
{
get { return someProperty; }
set
{
if (value == null)
MessageBox.Show("Why null????");
else
someProperty = value;
}
}
示例 2 - 在设计时禁用验证
您可以检查控件是否在 DesignMode
然后停止验证:
private SomeType someProperty = null;
public SomeType SomeProperty
{
get { return someProperty; }
set
{
if (value == null && !DesignMode)
MessageBox.Show("Why null????");
else
someProperty = value;
}
}
我在 Visual Studio 2019 年创建了一个 C# 用户控件。它有一个名为 "BoundLayout" 的 属性。
public Layout BoundLayout
{
get
{
return _Layout;
}
set
{
_Layout = value as Layout;
if (_Layout == null)
{
MessageBox.Show("Value submitted is not of type 'LAYOUT'","Invalid Value",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
InitializeControl();
}
}
}
如果程序试图将不兼容的值分配给 属性,则会在 MessageBox 中显示一条错误消息。这工作正常。
非常奇怪的是,每当我构建(不是 运行)项目时,此错误消息都会显示在其模态 MessageBox 中,必须先确认,然后才能 return 到 Visual Studio.在调试和发布模式下构建时会发生这种情况。添加到 属性 集代码的断点不会被触发。构建成功完成,没有错误或警告,我可以 运行 应用程序。
包括此用户控件在内的应用程序按预期运行。我以前从未遇到过这种行为。还有其他人吗?
用户控件的完整(仍在开发中)代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Dispatcher
{
public partial class DivisionModuleGrid : UserControl
{
private Layout _Layout = null;
private ObservableListSource<LayoutDivision> _LayoutDivisions;
private DivisionModulesList _activeDivision = null;
private int _divisionCount;
public Layout BoundLayout
{
get
{
return _Layout;
}
set
{
_Layout = value as Layout;
if (_Layout == null)
{
MessageBox.Show("Value submitted is not of type 'LAYOUT'","Invalid Value",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
InitializeControl();
}
}
}
public DivisionModulesList ActiveDivision
{
get
{
return _activeDivision;
}
set
{
_activeDivision = value as DivisionModulesList;
if (_activeDivision != null)
{
lbl_ActiveDivision.Text = _activeDivision.DivisionName;
}
else
{
lbl_ActiveDivision.Text = "-No Active Division-";
}
}
}
public DivisionModuleGrid()
{
InitializeComponent();
}
private void InitializeControl()
{
_LayoutDivisions = _Layout.LayoutDivisions;
_divisionCount = _LayoutDivisions.Count;
tbx_LayoutName.Text = _Layout.LayoutName;
// Grid Layout divide into Rows & Columns
int tlp_rows = _divisionCount / 3;
TableLayoutPanel tlp = (TableLayoutPanel)(Controls.Find("tlp_DivisionGrid", false)[0]);
DivisionModulesList dml;
foreach (LayoutDivision ld in _LayoutDivisions)
{
dml = new DivisionModulesList(ld);
dml.BoundDivision = ld;
tlp.Controls.Add(dml);
}
}
private void Tlp_DivisionGrid_Paint(object sender, PaintEventArgs e)
{
}
}
}
在为 UserControl 创建您自己的属性时,如果您在另一个地方使用此 UserControl,Designer 会为此 属性 生成代码,例如:
yourControl.BoundLayout = null;
在Designer.cs文件中搜索;直到重新生成代码才会解决问题
如果设计器显示您的控件,它会运行您的代码,并在设计时(不是生成时或运行时)显示您的 MessageBox。 永远避免这种情况
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
public Layout BoundLayout
在您的所有属性上,如果您打算仅通过代码而不是在设计器中对其进行修改,尤其是当 null 是无效值时。
当在另一个地方再次使用您的 UserControl 时,它不会再创建此 BoundLayout=null,但是对于您的 UserControl 的现有引用,您必须手动删除此行。
一般建议:一般来说,您应该抛出异常而不是显示 MessageBox。但这与问题无关。
您已将 属性 的初始值定义为 null。这意味着,当您在窗体上放置一个控件实例时,它也会序列化空赋值并生成如下代码:
userControl1.Name = "userControl1";
userControl1.Size = new Size( 100, 100);
userControl1.SomeProperty = null;
...
要解决此问题,您可以使用以下任一选项:
- 防止设计器序列化为 null 的值。
- 在设计时禁用验证。
- 防止设计器始终序列化该值。 (同样由 Holger 提出)
示例 1 - 防止设计器序列化值为 null 的值
您可以使用 DefaultValue
属性将 属性 的默认值设置为 null。然后,当您将控件放在窗体上或在设计时将空值分配给 属性 时,当 属性 的值为 null 时,它不会被设计器序列化。
private SomeType someProperty = null;
[DefaultValue(null)]
public SomeType SomeProperty
{
get { return someProperty; }
set
{
if (value == null)
MessageBox.Show("Why null????");
else
someProperty = value;
}
}
示例 2 - 在设计时禁用验证
您可以检查控件是否在 DesignMode
然后停止验证:
private SomeType someProperty = null;
public SomeType SomeProperty
{
get { return someProperty; }
set
{
if (value == null && !DesignMode)
MessageBox.Show("Why null????");
else
someProperty = value;
}
}