【发布时间】:2013-07-25 18:29:40
【问题描述】:
我有 UserControl,一半在 VS Designer 中创建,一半在代码中创建。
我想从代码中创建此 UserControl 的新实例,但每次都将其一些默认属性设置为不同的值。
示例(编辑真实代码):
// in my Main Form..
var newFrame = new RPictureFrame(); // my UserControl
newFrame.Width = 50;
newFrame.Height = 50;
newFrame.Location = new Point(0,0);
this.Controls.Add(newFrame);
newFrame = new RPictureFrame();
newFrame.Width = 200;
newFrame.Height = 400;
newFrame.Location = new Point(0,150);
this.Controls.Add(newFrame);
原错误示例:
var newMyUserControl1 = new MyUserControl();
newMyUserControl1.size.Width = 50;
var newMyUserControl2 = new MyUserControl();
newMyUserControl2.size.Width = 200;
有时会发生的情况是,我在创建新控件实例后立即设置的新值似乎被忽略了。
我唯一的解释是,由于我的 UserControl 是在 Designer 中设计的,因此它的所有默认属性实际上都序列化在 .resx 文件中(?)。当我在运行时创建新实例时,会在单独的线程中启动反序列化(我无法控制)。当我在反序列化之前意外设置了一些属性时,我的值会立即被 ser 的值覆盖。
我没有找到任何关于如何创建设计师创建的控件的信息,所以这当然只是我的猜测。
我的问题是,如何绕过它?可能是一些简单的方法。
我尝试过的事情:
1- 在我的 UserControl 代码中:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Size size;
..从设计时序列化中删除标准属性。 但是(编译器说)我只是隐藏了现有的标准属性。 加上它当然不起作用。 我仍然是 c# 和 .NET 的初学者,所以也许我做错了?
2- 我想我可以订阅每个新控件的 (on)Load 事件,让它完全反序列化,然后设置我需要的内容。但它在代码中似乎非常繁琐,属性将不必要地设置两次(或更多)等。 基本上我不相信没有更优雅的解决方案:)
很高兴得到任何建议
【问题讨论】:
-
您正落入一个标准的.NET 陷阱,每个程序员迟早都会落入该陷阱。您的“大小”属性返回值的副本。因为 Size 是一个值类型。分配 Width 属性只会更新该副本。多注意格伦的回答,他展示了正确的设置方法。
-
@Hans Passant 和 Glenn Cuevas:你们俩确实是对的。大小类型是一个结构,它的值不能像我在上面的例子中那样改变。 --尽管我写了,我的例子只是作为解释,并没有显示我的真实代码。我认为这不是一个好方法(下次注意:)。我已经编辑了 OP 示例以使其有意义。 - 我的问题仍然存在,因为问题仍然存在,如果我以正确的方式分配控件的属性(在新示例中)。 IE。我设置的属性值不会坚持。
-
好吧,您发现在 SO 问题中发布虚假代码总是一个真的坏主意。贴出真实代码。
-
你是对的。完成。--(抱歉,感谢您的耐心。这是我第一次使用 stackoverflow,所以我正在尝试最好的方式来解释事情。)
-
Generaly 你能告诉我我对对象反序列化的假设是否正确吗?
标签: c# winforms windows-forms-designer resx