سؤال

أنا مشغول في كتابة قالب رموز رموز يحتوي على واحدة من خصائصها كنوع System.Type. وبعد أريد أن أكون قادرا على تحديد النوع باستخدام UI يختار التجميع، وتحميل التجميع ثم يعرض الأنواع المتوفرة في تلك التجميع. يمكنني بعد ذلك الذهاب واختيار واحدة من الأنواع.

هل واجه أي شخص أو كود مكتوب يقوم بهذا أو شيء مماثل؟

هل كانت مفيدة؟

المحلول

ليس لدي أي شيء يستحقه، لكنه ليس من الصعب بشكل كبير أن يطرق واحدة ... أكبر gotcha هي مسألة عدم تفريغ DLLS ... ولكن مثال عن طريق الخام:

(يستخدم هذا السلسلة AssemblyQualifiedName, ، ولكن 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