我有一个datagridview,显示我的集合中的所有对象。显示的对象位于基类中。但实际上有+ - 8个不同的派生类。
为了让用户向对象添加对象特定信息,当用户双击行Dim x As New Cylinder_form
x.Show()
时,我会打开一个新表单,该行将有额外的字段来添加特定信息。
我现在的问题是,如何通过双击用户将所选对象传递给新表单?我不知道该怎么做。首先,我认为这有点像使用子函数Byval
Byref
。或者我可以创建一个公共变量来保存所选对象并从我的新表单引用该变量?
最常见的做法是什么?
答案 0 :(得分:2)
在几个表单之间传递对象的主要问题的最简单的解决方案是将实例化对象传递给编辑表单的构造函数,在保存时更改所有属性,然后照常继续。
例如:
在Mainform中作为CylinderAdd的处理程序:
Sub addCylinder() Handles btCylinder.Click
Dim cylinder As New Cylinder
Dim sw As New ShapeWindow(cylinder)
'blocks mainUI until edit is conformed
sw.showDialog()
'Use Object however you want in your mainform
End Sub
并在用于设置属性的表单中,您可以创建如下构造函数:
Sub New(obj As Cylinder)
' This call is required by the designer.
InitializeComponent()
'use your shape if it had meaningful default values to initialize form fields
End Sub
该示例仅显示如何为全新对象执行此操作,如果您已有对象(例如在数据网格中)并且只想编辑它,则只需相应地调整代码。
关于Hans Passant建议的属性网格,请尝试阅读此link on Code Project或尝试查看msdn here。
或者,如果您熟悉使用反射并希望对属性表单的光学外观有更多影响,则可以使用反射来获取图形对象的所有公共属性并以纯粹的方式构建UI程序化方式,但这取决于您的偏好当然,如果您相应地构建对象,通常属性网格应该足够。
无论如何使用propertygrid或者反射,你都可以在一个窗口中完成所有数字
答案 1 :(得分:2)
给定一个具有公共属性的MustInherit
基类,多个子类包含更具体类型的props和BindingList
来存储它们并在DataGridView
中显示它们, PropertyGrid
可以很好地编辑这些内容。
为此,DGV会显示它们,显然让用户通过拖放重新排序(按照上一个问题)。存储为BaseShape
,然后DGV不会显示更具体的类型属性,但它可以充当“选择器”。
为此,您可以使用RowHeaderMouseDoubleClick
事件作为编辑该项目的信号:
Dim shapeObj = CType(dgv.Rows(e.RowIndex).DataBoundItem, BaseShape)
Dim thisShape = shapeList.FirstOrDefault(Function(x) x.Index = shapeObj.Index)
If thisShape IsNot Nothing Then
propGrid.SelectedObject = thisShape
End If
这使用index属性从基础列表中获取正确的项目,然后将其显示在PropertyGrid
中。我怀疑Index
的意思是“序列”,也许它们会在拖放行时发生变化。如果是这样,我也会有某种不可变的ID属性,因此每个对象都可以被唯一标识。
结果:
如果您有DONE按钮,可以添加此按钮以强制刷新属性:
propGrid.SelectedObject = Nothing
shapeList.ResetBindings()
使这个非常简单的事情是对PropertyGrid中对象的编辑自动流到列表和DataGridView
。您不必将对象传递给其他东西或设计特殊形式。可以看出,您可以使用Attributes
控制相当多的显示方式:有些是只读的,它们是分类的。任何“系统”属性,例如Id或者索引,也可以很容易地从视图中隐藏。
如果您想要一种取消/放弃道具网格编辑的方法,请克隆所选对象,显示它,然后替换列表中的现有项目。
这也可用于定义要添加的新形状。当用户从组合中选择“新金字塔”时,创建一个并在PropertyGrid中显示它以供他们编辑。完成后,将其添加到列表中以显示在DGV中。