代码之家  ›  专栏  ›  技术社区  ›  AnthonyWJones

访问uitypeeditor的editValue中的其他上下文数据

  •  4
  • AnthonyWJones  · 技术社区  · 14 年前

    我正在调整WinForms应用程序。此应用程序具有 Form 包含一个 PropertyGrid . 对象被分配给 SelectedObject 属性,以便属性网格显示对象的属性。

    指定对象的类型具有一个属性,该属性包含 EditorAttribute 指定一个 UITypeEditor .

    本次实施 UTI编辑器 收益率 UITypeEditorEditStyle.Drop 在它的覆盖 GetEditStyle 方法。它的 EditValue 方法显示 ListBox 从中可以分配实例属性的值。

    到目前为止一切都很好。

    现在我有了一个附加的要求,要求根据 形式 托管 属性表格 . 我不知道如何将这些上下文信息 编辑价值 方法。

    上面好像没有什么 context 参数,即使我尝试将其强制转换为更具体的类型。我也不知道如何添加其他服务来从 provider .

    有什么想法吗?

    3 回复  |  直到 12 年前
        1
  •  2
  •   Marc Gravell    14 年前

    我想知道你想做的是不是比 TypeConverter 通过 GetStandardValues ?但不管怎样,两者都是 context.Instance context.PropertyDescriptor 似乎 在快速测试中填充 GetEditStyle EditValue ):

    using System;
    using System.ComponentModel;
    using System.Drawing.Design;
    using System.Windows.Forms;
    class MyData
    {
        [Editor(typeof(MyEditor), typeof(UITypeEditor))]
        public string Bar { get; set; }
    
        public string[] Options { get; set; }
    }
    class MyEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            // break point here; inspect context
            return UITypeEditorEditStyle.DropDown;
        }
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            // break point here; inspect context
            return base.EditValue(context, provider, value);
        }
    
    }
    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form
            {
                Controls =
                {
                    new PropertyGrid {
                        Dock = DockStyle.Fill,
                        SelectedObject = new MyData()
                    }
                }
            });
        }
    }
    

    或作为类型转换器:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    class MyData
    {
        [TypeConverter(typeof(MyConverter))]
        public string Bar { get; set; }
    
        public string[] Options { get; set; }
    }
    class MyConverter : StringConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            MyData data = (MyData)context.Instance;
            if(data == null || data.Options == null) {
                return new StandardValuesCollection(new string[0]);
            }
            return new StandardValuesCollection(data.Options);
        }
    }
    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form
            {
                Controls =
                {
                    new PropertyGrid {
                        Dock = DockStyle.Fill,
                        SelectedObject = new MyData()
                    }
                }
            });
        }
    }
    
        2
  •  4
  •   Community kfsone    7 年前

    在类似的情况下,我想将一个对象注入到自定义的UItypeEditor的构造函数中。

    我跟随尼古拉斯·卡迪尔哈克的评论 Here 把功劳都给他。它使用了typescriptionProvider。

    这是完整的代码集。

    class Foo
    {
        public Foo() { Bar = new Bar(); }
        public Bar Bar { get; set; }
    }
    
    class Bar
    {
        public string Value { get; set; }
    }
    
    class BarTypeDescriptionProvider : TypeDescriptionProvider
    {
        private TypeDescriptionProvider _baseProvider;
        string _extraParam;
    
        public BarTypeDescriptionProvider(Type t, string extraParam)
        {
            this._extraParam = extraParam;
            _baseProvider = TypeDescriptor.GetProvider(t);
        }
    
        public string ExtraParam
        { 
            get { return _extraParam; } 
        }
    
        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            return new BarTypeDescriptor(this, _baseProvider.GetTypeDescriptor(objectType, instance), objectType);
        }
    }
    
    
    class BarTypeDescriptor : CustomTypeDescriptor
    {
        private Type _objectType;
        private BarTypeDescriptionProvider _provider;
    
        public BarTypeDescriptor(BarTypeDescriptionProvider provider,  ICustomTypeDescriptor descriptor, Type objectType): base(descriptor)
        {
            if (provider == null) throw new ArgumentNullException("provider");
            if (descriptor == null)
                throw new ArgumentNullException("descriptor");
            if (objectType == null)
                throw new ArgumentNullException("objectType");
            _objectType = objectType;
            _provider = provider;
        }
    
        public override object GetEditor(Type editorBaseType)
        {
            return new BarEditor(_provider.ExtraParam);
        }
    }
    
    
    class BarEditor : UITypeEditor
    {
        private string _extraParam;
        public BarEditor(string x)
            : base()
        {
            _extraParam = x;
        }
    
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            MessageBox.Show(_extraParam);
            return base.EditValue(context, provider, value);
        }
    }
    
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
            string extraParam = "Extra param from main form";
    
            TypeDescriptor.AddProvider(new BarTypeDescriptionProvider(typeof(Bar), extraParam), typeof(Bar));
    
            this.propertyGrid1.SelectedObject = new Foo();
        }
    }
    

    迈克尔

        3
  •  1
  •   Jordy Boom    12 年前

    在重写的EditValue方法中, context.Container 将提供编辑器所属的对象。这个 context.Container.Components 属性将列出包含窗体及其所有子级的所有控件。

    推荐文章