有没有办法在属性网格之外使用 CollectionEditor?

3

我正在替换我的属性网格,以便能够更好地自定义我的用户界面。我在我的表单上放置了一个按钮,希望当点击时弹出CollectionEditor并允许我修改我的代码。当我使用PropertyGrid时,我只需要为属性添加一些指向我的CollectionEditor的属性即可工作。但是如何手动调用CollectionEditor呢?谢谢!

2个回答

12

在这里找到答案:http://www.devnewsgroups.net/windowsforms/t11948-collectioneditor.aspx

以防该链接网站将来消失了,这里简要介绍一下。以下代码与上述链接完全相同,只是注释是我的。

假设您有一个包含ListBox和Button的窗体。如果您想使用CollectionEditor编辑ListBox中的项目,则应在事件处理程序中执行以下操作:

private void button1_Click(object sender, System.EventArgs e)
{
    //listBox1 is the object containing the collection.  Remember, if the collection
    //belongs to the class you're editing, you can use this
    //Items is the name of the property that is the collection you wish to edit.
    PropertyDescriptor pd = TypeDescriptor.GetProperties(listBox1)["Items"];
    UITypeEditor editor = (UITypeEditor)pd.GetEditor(typeof(UITypeEditor));
    RuntimeServiceProvider serviceProvider = new RuntimeServiceProvider();
    editor.EditValue(serviceProvider, serviceProvider, listBox1.Items);
}

现在你需要做的下一件事情是创建RuntimeServiceProvider()。这是链接中作者编写的实现代码:

public class RuntimeServiceProvider : IServiceProvider, ITypeDescriptorContext
{
    #region IServiceProvider Members

    object IServiceProvider.GetService(Type serviceType)
    {
        if (serviceType == typeof(IWindowsFormsEditorService))
        {
            return new WindowsFormsEditorService();
        }

        return null;
    }

    class WindowsFormsEditorService : IWindowsFormsEditorService
    {
        #region IWindowsFormsEditorService Members

        public void DropDownControl(Control control)
        {
        }

        public void CloseDropDown()
        {
        }

        public System.Windows.Forms.DialogResult ShowDialog(Form dialog)
        {
            return dialog.ShowDialog();
        }

        #endregion
    }

    #endregion

    #region ITypeDescriptorContext Members

    public void OnComponentChanged()
    {
    }

    public IContainer Container
    {
        get { return null; }
    }

    public bool OnComponentChanging()
    {
        return true; // true to keep changes, otherwise false
    }

    public object Instance
    {
        get { return null; }
    }

    public PropertyDescriptor PropertyDescriptor
    {
        get { return null; }
    }

    #endregion
}

1
+1 太棒了的解决方案。唯一的缺点似乎是我不能看到用户是否按下了“取消”。我有什么遗漏吗? - Brad

1

由于我无法评论,我会在这里发帖:

您可以通过在WindowsFormsEditorService.ShowDialog的CollectionEditor的okButton上添加Click事件来获取DialogResult。

public System.Windows.Forms.DialogResult ShowDialog(Form dialog)
{
    ((System.Windows.Forms.Button)dialog.Controls.Find("okButton", true)[0]).Click += WindowsFormsEditorService_Click;
    return dialog.ShowDialog();
}

...

private void WindowsFormsEditorService_Click(object sender, EventArgs e)
{
    dr = DialogResult.OK;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接