我正在使用PropertyGrid类来编辑应用程序中的对象。这些是相关的类(或更确切地说,简化):
public class Inner
{
public int A { get; set; }
public string B { get; set; }
}
public class Outer
{
public List<Inner> InnerData { get; set; }
public int Id { get; set; }
}
我将Outer类型的对象设置为属性网格的SelectedObject字段。当一个外部对象将其InnerData属性设置为null时,就会出现问题。 Null被认为是此属性的可接受值,因为InnerData属性表示“可选”数据,并且未指定它与指定空列表不同。理想情况下,我希望用户能够通过指定新列表的组件,修改现有的非null InnerData值,并将现有的InnerData值替换为null来将null InnerData属性替换为实际值。
有人知道如何实现这一目标吗?
答案 0 :(得分:1)
看看创建UITypeEditor,我认为如果你使用编辑器,你将有更多的控制列表,并能够判断当前值是否为null,如果是这样,你可以让编辑器显示一个空格或者可以添加或删除列表项的东西,你也可以添加一个复选框来告诉编辑器再次返回null并在属性上设置null,编辑器基本上是一个WinForm,所以你几乎可以做任何事情。
internal class GenericTypeEditor : UITypeEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService winFormEditorSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
using (MyForm editorForm = new MyForm())
{
if (winFormEditorSvc.ShowDialog(editorForm) == System.Windows.Forms.DialogResult.OK)
value = editorForm.ReturnObject;
}
return value; //this can be null if you wish
}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
然后只需在您的属性上设置属性
[EditorAttribute(typeof(GenericTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List<Inner> InnerData { get; set; }
这篇文章过去帮助了我,也许对你有所帮助: http://msdn.microsoft.com/en-us/library/ms171840(v=vs.100).aspx
答案 1 :(得分:0)
属性网格尝试将新的内部项添加到InnerData对象,但由于您尚未初始化它,因此属性网格无法保存添加的项。在Outter中需要一个构造函数,它将初始化InnerData,就像一个新的List一样。您不必将任何项目放入其中,用户可以在运行时执行此操作,也可以将其清空,但需要初始化InnerData列表对象。
如果您只想将Inner作为属性,请将System.ComponentModel添加到您的使用中并尝试此操作
[TypeConverter(typeof(ExpandableTypeConverter))]
public Inner DefaultInner { get; set; }
这将使您的对象在属性网格中可扩展,以便您可以设置其嵌套属性
尝试处理PropertyGrid.SelectedGridItemChanged事件:
private void propertyGrid1_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
if ((e.NewSelection.Label == "InnerData") && (_outter.InnerData == null)) _outter.InnerData = new List<Inner>();
}
然后,只要选择了InnerData项,如果集合为null,则将其初始化为新列表。