System.type 인스턴스를 선택하는 uitypeeditor가있는 사람이 있습니까?

StackOverflow https://stackoverflow.com/questions/1298643

  •  18-09-2019
  •  | 
  •  

문제

나는 속성 중 하나가 유형으로 된 코드 메스 템플릿을 작성하는 데 바쁘다 System.Type. 어셈블리를 선택하고 어셈블리를로드 한 다음 해당 어셈블리에서 사용 가능한 유형을 표시하는 UI를 사용하여 유형을 선택할 수 있기를 원합니다. 그런 다음 가서 유형 중 하나를 선택할 수 있습니다.

이 작업을 수행하거나 비슷한 일을하는 사람이 있습니까?

도움이 되었습니까?

해결책

나는 손을 잡을 것이 없지만, 하나를 두드리는 것은 그리 어렵지 않습니다 ... 가장 큰 Gotcha는 DLL을 내리지 않는 문제입니다 ... 그러나 조잡한 예입니다.

(이것은 문자열을 사용합니다 AssemblyQualifiedName, 그러나 a Type 사실상 동일하게 작동 - 약 3 줄을 변경합니다)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;

class MyData {
    [Editor(typeof(TypeTypeEditor), typeof(UITypeEditor))]
    [DisplayName("Some Type"), Description("Which type to use...")]
    public string SomeType { get; set; }

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.Run(new Form {
            Controls = {
                new PropertyGrid { 
                    Dock = DockStyle.Fill,
                    SelectedObject = new MyData()
                }
            }
        });
    }
}

class TypeTypeEditor : UITypeEditor {
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value) {
        IWindowsFormsEditorService svc = provider == null ? null
            : provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
        if (svc != null) {
            using(TypeForm form = new TypeForm()) {
                form.TypeName = Convert.ToString(value);
                if (svc.ShowDialog(form) == DialogResult.OK) {
                    value = form.TypeName;
                }
            }
        }
        return value;
    }
}
class TypeForm : Form {
    public string TypeName { get; set; }
    Button ok, load;
    TreeView tree;
    public TypeForm() {
        Text = "Select type";
        ok = new Button { Text = "OK" };
        ok.Enabled = false;
        ok.DialogResult = DialogResult.OK;
        load = new Button { Text = "Load..." };
        load.Dock = ok.Dock = DockStyle.Bottom;
        this.AcceptButton = ok;
        tree = new TreeView();
        tree.Dock = DockStyle.Fill;
        load.Click += load_Click;
        Controls.Add(load);
        Controls.Add(ok);
        Controls.Add(tree);
        tree.AfterSelect += tree_AfterSelect;
    }

    void tree_AfterSelect(object sender, TreeViewEventArgs e) {
        ok.Enabled = false;
        if (e.Node != null && e.Node.Tag != null) {
            string s = Convert.ToString(e.Node.Tag);
            if (!string.IsNullOrEmpty(s)) {
                TypeName = s;
                ok.Enabled = true;
            }            
        }
    }

    void load_Click(object sender, EventArgs e) {
        try {
            string path = null;
            using (OpenFileDialog dlg = new OpenFileDialog()) {
                dlg.Filter = "dll|*.dll|exe|*.exe";
                if (dlg.ShowDialog(this) == DialogResult.OK) {
                    path = dlg.FileName;
                }
            }
            if (!string.IsNullOrEmpty(path)) {
                Assembly asm = Assembly.LoadFrom(path);
                SortedList<string, TreeNode> namespaces = new SortedList<string, TreeNode>();
                foreach (Type type in asm.GetTypes()) {
                    if (!type.IsPublic) continue;
                    TreeNode nsNode;
                    if (!namespaces.TryGetValue(type.Namespace, out nsNode)) {
                        nsNode = new TreeNode(type.Namespace);
                        namespaces.Add(type.Namespace, nsNode);
                    }
                    nsNode.Nodes.Add(type.Name).Tag = type.AssemblyQualifiedName;
                }
                tree.BeginUpdate();
                tree.Nodes.Clear();
                try {
                    foreach (TreeNode node in namespaces.Values) {
                        tree.Nodes.Add(node);
                    }
                }
                finally {
                    tree.EndUpdate();
                }
            }
        }
        catch (Exception ex) {
            MessageBox.Show(this, ex.Message, ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top