编译期间显示的用户控制错误消息

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;
    }
}