System.type 인스턴스를 선택하는 uitypeeditor가있는 사람이 있습니까?
-
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);
}
}
}
제휴하지 않습니다 StackOverflow