在PropertyGrids中是否有更好的StringCollection编辑器可供使用?

4

我在我的应用程序框架的配置编辑器中大量使用属性表(PropertySheets)。我很喜欢它们,因为一旦你学会了如何使用,就很容易处理它们并使编辑变得非常可靠。

我的配置中存储了Python脚本。虽然可以在StringCollection编辑器中编辑Python脚本(这是我一直在使用的),但"可能"与"可用"之间有很长的距离。 我希望有一个编辑器,支持可调大小和等宽字体,保留空行,甚至能进行语法高亮显示,真心希望这个愿望单能实现。

如果必要,我当然可以自己编写这个编辑器,但我宁愿不这样做。

我在Google上查找了一下,没有找到类似我所描述的东西,所以我想在这里问一下。这是一个解决过的问题吗?是否已经有人尝试构建更好的编辑器?

2个回答

4
您可以轻松地创建自己的字符串集合编辑器,只需按照以下简单步骤进行操作。 此示例使用C#。

1)您必须创建一个编辑器控件,并从System.Drawing.Design.UITypeEditor派生它。我称之为StringArrayEditor。因此,我的类以以下方式开始:

public class StringArrayEditor : System.Drawing.Design.UITypeEditor

PropertyGrid控件需要知道编辑器是模态的,当选择相关属性时,它将显示省略号按钮。因此,您必须按照以下方式重写GetEditStyle

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

最后,编辑控件必须覆盖 EditValue 操作,以便它知道用户在单击属性的省略号按钮时要如何继续。以下是覆盖操作的完整代码:
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
        if (editorService != null)
        {
            var selectionControl = new TextArrayPropertyForm((string[])value, "Edit the lines of text", "Label Editor");
            editorService.ShowDialog(selectionControl);
            if (selectionControl.DialogResult == DialogResult.OK)
                value = selectionControl.Value;
        }
        return value ?? new string[] {};
    }

当用户点击省略号时,会调用此覆盖方法。我们将editorService设置为编辑表单的接口。它被设置为我们尚未创建的表单,我称其为TextArrayPropertyForm。实例化TextArrayPropertyForm,并传入要编辑的值。为了保险起见,我还传递了两个字符串,一个用于表单标题,另一个用于顶部的标签,解释用户应该做什么。它以模态方式显示,如果单击了OK按钮,则使用从我们即将创建的表单中设置的selectionControl.Value值更新值。最后,此值在覆盖方法的末尾返回。
第二步)创建编辑器表单。在我的情况下,我创建了一个带有2个按钮(buttonOKbuttonCancel),一个标签(labelInstructions)和一个文本框(textValue)来模仿默认的StringCollection编辑器。代码非常简单,但是如果您感兴趣,可以看一下这里的代码。
using System;
using System.Windows.Forms;

namespace MyNamespace
{
    /// <summary>
    /// Alternate form for editing string arrays in PropertyGrid control
    /// </summary>
    public partial class TextArrayPropertyForm : Form
    {
        public TextArrayPropertyForm(string[] value,
            string instructions = "Enter the strings in the collection (one per line):", string title = "String Collection Editor")
        {
            InitializeComponent();
            Value = value;
            textValue.Text = string.Join("\r\n", value);
            labelInstructions.Text = instructions;
            Text = title;
        }

        public string[] Value;

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            Value = textValue.Text.Split(new[] { "\r\n" }, StringSplitOptions.None);
            DialogResult = DialogResult.OK;
        }
    }
}

步骤3)告诉 PropertyGrid 使用备用编辑器。与 PropertyGrid 控件中使用的其他任何属性之间的区别在于 [Editor] 行。

    [Description("The name or text to appear on the layout.")]
    [DisplayName("Text"), Browsable(true), Category("Design")]
    [Editor(typeof(StringArrayEditor), typeof(System.Drawing.Design.UITypeEditor))]
    public string[] Text {get; set;}

现在,当您在窗体上创建一个PropertyGrid并设置为包含此Text属性的类时,它将在您自定义的表单中进行编辑。有无数的机会可以按照您选择的方式更改自定义表单。通过修改,这将适用于编辑任何您喜欢的类型。重要的是,编辑器控件返回与覆盖的EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)方法中的属性相同的类型。
希望对您有所帮助!

2
您需要编写自己的类型编辑器。您可以将其视为用户控件,因为当您编写自己的类型编辑器时,您提供了属性网格编辑属性时显示的 UI 控件。因此,您可以创建几乎任何操作的类型编辑器,这意味着如果您有第三方编辑器控件,您可以将其包含在类型编辑器中。
一些资源可帮助您入门:

Scott,你能添加一些有用资源的链接来解释你的方法吗?这将会大大改善你的回答,并且可能会得到一些赞同。 - Eric Schoonover

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