Pregunta

Estoy ocupado escribiendo una plantilla CodeSmith que tiene una de sus propiedades como el tipo System.Type. Quiero ser capaz de seleccionar el tipo de uso de una interfaz de usuario que recoge el montaje, carga el ensamblado y luego muestra los tipos que están disponibles en esa asamblea. A continuación, puedo ir a recoger uno de los tipos.

Alguien ha encontrado o código que hace esto o algo similar por escrito?

¿Fue útil?

Solución

No tengo nada a cambio, pero no es enormemente difícil de derribar uno para arriba ... el mayor Gotcha es la cuestión de no descargar los archivos DLL ... sino un crudo ejemplo:

(este utiliza el AssemblyQualifiedName cadena, pero una Type funciona prácticamente idéntica - sólo cambia alrededor de 3 líneas)

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);
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top