1

我正在使用 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 字段。当 Outer 对象的 InnerData 属性设置为 null 时,就会出现问题。Null 被认为是此属性的可接受值,因为 InnerData 属性表示“可选”数据,并且不指定它与指定空列表不同。理想情况下,我希望用户能够通过指定新列表的组件、修改现有的非空 InnerData 值并将现有的 InnerData 值替换为空来将空 InnerData 属性替换为实际值。

有人知道如何做到这一点吗?

4

2 回答 2

1

看看创建 UITypeEditor,我认为如果您使用编辑器,您将对列表有更多的控制权,并且能够判断当前值是否为空,如果是,您可以让编辑器显示空白网格或其他地方可以添加或删除列表项,您还可以添加一个复选框来告诉编辑器再次返回 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

于 2012-10-24T01:27:47.847 回答
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>();
}

Then whenever the InnerData item is selected, if the collection is null, its initialized to a new list.

于 2012-10-23T23:58:17.853 回答