我创建了一个具有最大值的自定义控件。添加if时(DesignMode)Parent.Refresh();它编译但在客户端它崩溃与消息错误:
对象引用未设置为对象的实例
调用堆栈:
at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at Microsoft.VisualStudio.Shell.Design.VsTargetFrameworkPropertyDescriptor.SetValue(Object component, Object value)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
源代码:
[Category("Main")]
[Description("Max Value")]
[DefaultValue(100)]
public int Max
{
get { return _max; }
set {
_max = value;
if (DesignMode)
{
Parent.Refresh();
}
}
}
答案 0 :(得分:5)
试试这个:
if (DesignMode && Parent != null)
{
Parent.Refresh();
}
当第一次设置值时,很可能控件尚未添加到其Parent中。
如果您查看表单的* .designer.cs,您会注意到在将添加到父表单之前,您的usercontrol的属性已分配。这就是你得到例外的原因。
答案 1 :(得分:2)
我有类似的问题。组件代码导致此错误。 在我的案例中,简单的解决方案是封装所有使用图形组件的代码:
if (this.Created)
{
// insert code with other components here
}
不幸的是,此解决方案无法使用选项卡控件(当组件不在第一个可见选项卡上时)。
在我的情况下,问题是由财产引起的。该属性具有子组件的主动初始化。最终的解决方案是:
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[Category("Main")]
[Description("...")]
[DefaultValue(MyDataClass.None)]
public MyDataClass Data
{
get
{
return this.data;
}
set
{
if (object.ReferenceEquals(value, null))
value = MyDataClass.None; // not null - valid state of no data
if (this.Created)
{
this.textEdit.Text = value.ToString();
}
this.data = value;
}
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (!this.DesignMode)
this.Data = this.data;
}
要消除错误,请使用[Browsable(false)]
或覆盖OnVisibleChanged
。
答案 2 :(得分:0)
您还必须为Parent检查null,并确保您正在设置Parent对象,或者Parent.Refresh()将永远不会执行。
答案 3 :(得分:0)
我只运行代码并从适当的菜单中打开该表单。然后进行截屏并保存图像。然后转到解决方案资源管理器,打开“ .designer.cs”文件,复制代码并将其保存在记事本中。现在再次打开设计器,然后单击“忽略并继续”并确认。它为我工作。但是,如果缺少某些控件,则可以通过拖放创建该控件,然后查看保存的屏幕截图和“ .designer.cs”文件,以使该控件与以前一样。