c# - 复制粘贴在属性网格中被禁用

标签 c# copy-paste propertygrid typeconverter uitypeeditor

我在属性网格中有一个 FileNameEditor,它有一些条目,例如

主文件:“C:\blah1”

安全文件:“C:\blah2”

等等。

我的问题是我无法从一个属性条目复制并粘贴到另一个属性条目,而且我也无法手动输入字段。是否有一个特定的属性可以在 FileNameEditor 中启用编辑。 示例

public class MyEditor : FileNameEditor
{
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    {
        return false;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)

    {

        object e = base.EditValue(context, provider, value);

        if ((value as MyFileS) != null)
        {
            (value as MyFilesS).FileName = (String) e;
        }

        return e;
    }

    protected override void InitializeDialog(OpenFileDialog openFileDialog)
    {
        base.InitializeDialog(openFileDialog);
    }
}

谢谢

最佳答案

为什么要使用自定义编辑器?如果您只想在对象上使用字符串属性,那么 Marc Gravell 的答案就可以了。

但是,如果属性网格中对象的"file"属性是自定义类,您还需要实现自定义类型转换器。

例如:

namespace WindowsFormsApplication
{
    using System;
    using System.ComponentModel;
    using System.Drawing.Design;
    using System.Globalization;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;

    class MyEditor : FileNameEditor
    {
        public override bool GetPaintValueSupported(ITypeDescriptorContext context)
        {
            return false;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            string s = Environment.CurrentDirectory;
            object e = base.EditValue(context, provider, value);
            Environment.CurrentDirectory = s;

            var myFile = value as MyFile;
            if (myFile != null && e is string)
            {
                myFile.FileName = (string)e;
                return myFile;
            }

            return e;
        }
    }

    class MyFileTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;

            return base.CanConvertFrom(context, sourceType);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(string))
                return true;

            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
                return new MyFile { FileName = (string)value };

            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var myFile = value as MyFile;
            if (myFile != null && destinationType == typeof(string))
                return myFile.FileName;

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

    [TypeConverter(typeof(MyFileTypeConverter))]
    [Editor(typeof(MyEditor), typeof(UITypeEditor))]
    class MyFile
    {
        public string FileName { get; set; }
    }

    class MyFileContainer
    {
        public MyFileContainer()
        {
            File1 = new MyFile { FileName = "myFile1.txt" };
            File2 = new MyFile { FileName = "myFile2.txt" };
        }

        public MyFile File1 { get; set; }
        public MyFile File2 { get; set; }
    }

    static public class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            using (var f = new Form())
            using (var pg = new PropertyGrid())
            {
                pg.Dock = DockStyle.Fill;
                pg.SelectedObject = new MyFileContainer();
                f.Controls.Add(pg);
                Application.Run(f);
            }
        }
    }
}

为了支持就地编辑文件名以及剪切和粘贴,PropertyGrid 需要知道如何将字符串转换为您的"file"类型并再次转换回来。如果您没有在 TypeConverter 中实现转换为字符串的方法,该属性将显示对象的 ToString() 的结果。

我建议拿出 Reflector.Net 并阅读 BCL 中一些 UITypeEditors 和 TypeConverter 的源代码,因为它可以提供很多信息,以了解 Microsoft 如何支持在属性网格中编辑 Color、TimeSpan、DateTime 等。

另外,打开文件对话框时要小心。如果您不小心,标准的 WinForms 打开文件对话框可以更改应用程序的当前工作目录。我不认为 FileNameEditor 有这个问题,但我只在 Windows 7 下测试过。

关于c# - 复制粘贴在属性网格中被禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2264162/

相关文章:

c# - 如何使用 PrincipalContext 连接到本地主机?

c# - 在 Repeater 控件中找不到标签控件

c# - .Net PropertyGrid DropDownList - 返回值不同于显示值

c# - 如何在属性网格的自定义字段中显示相似值?

C# 强制 PropertyGrid 不扩展子类属性并在根级别显示它

c# - Moq VerifySet(Action) 替换过时的表达式编译错误

c# - MVC : The view found at '~/.../Index.cshtml' was not created

vba - 复制整个工作表并粘贴为值

Bash:有 CTRL-C 时如何中断此脚本?

C# 在从 Excel 复制的字符串中找不到空格