속성 그리드 컨트롤을 사용하지 않고 .NET Collection 편집기 사용
-
19-08-2019 - |
문제
내 양식에 PropertyGrid가 있습니다. 내 상사는 그것이 못 생겼다고 생각합니다. 꺼짐. 섞인 것 없는.
그는 멋지고 깔끔하고 깨끗한 형태를 원합니다. 캐치는 다음과 같습니다. 속성 중 하나는 집에서 재배 한 물건의 모음입니다. 그는이 컬렉션의 컬렉션 편집기를 좋아합니다.
나는 내 자신의 컬렉션 편집기를 만들 수 있다는 것을 알고 있습니다. 그러나 몇 시간의 코딩을 절약 할 수있는 깨끗하고 간단한 솔루션이 있습니까?
해결책
이 기능을 얻을 수 있습니다 UITypeEditor
(을 통해 TypeDescriptor
), 그러나 그것은 사소하지 않습니다 - 당신은 IServiceProvider
, an IWindowsFormsEditorService
, 그리고 이상적으로는 ITypeDescriptorContext
- 약간의 faff. 해당 도구에 익숙하지 않으면 손으로 수행하는 것이 더 간단 할 수 있습니다.
또는 - 살펴보십시오 SmartPropertyGrid.net, 대안 PropertyGrid
.
업데이트 : 여기에 작업 예제가 있습니다 ... 확실히 사소한 일이지만 코드를 훔치십시오. 드롭 다운이 아닌 모달 편집자에게만 작동합니다. 또한 "우려의 분리"의 좋은 예는 아닙니다. 그만큼 MyHelper
수업은 흥미로운 수업입니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
class Foo
{
public Foo() { Bars = new List<Bar>(); }
public List<Bar> Bars { get; private set; }
}
class Bar
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
Foo foo = new Foo();
Bar bar = new Bar();
bar.Name = "Fred";
bar.DateOfBirth = DateTime.Today;
foo.Bars.Add(bar);
Application.EnableVisualStyles();
using(Form form = new Form())
using (Button btn = new Button())
{
form.Controls.Add(btn);
btn.Text = "Edit";
btn.Click += delegate
{
MyHelper.EditValue(form, foo, "Bars");
};
Application.Run(form);
}
}
}
class MyHelper : IWindowsFormsEditorService, IServiceProvider, ITypeDescriptorContext
{
public static void EditValue(IWin32Window owner, object component, string propertyName) {
PropertyDescriptor prop = TypeDescriptor.GetProperties(component)[propertyName];
if(prop == null) throw new ArgumentException("propertyName");
UITypeEditor editor = (UITypeEditor) prop.GetEditor(typeof(UITypeEditor));
MyHelper ctx = new MyHelper(owner, component, prop);
if(editor != null && editor.GetEditStyle(ctx) == UITypeEditorEditStyle.Modal)
{
object value = prop.GetValue(component);
value = editor.EditValue(ctx, ctx, value);
if (!prop.IsReadOnly)
{
prop.SetValue(component, value);
}
}
}
private readonly IWin32Window owner;
private readonly object component;
private readonly PropertyDescriptor property;
private MyHelper(IWin32Window owner, object component, PropertyDescriptor property)
{
this.owner = owner;
this.component = component;
this.property = property;
}
#region IWindowsFormsEditorService Members
public void CloseDropDown()
{
throw new NotImplementedException();
}
public void DropDownControl(System.Windows.Forms.Control control)
{
throw new NotImplementedException();
}
public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form dialog)
{
return dialog.ShowDialog(owner);
}
#endregion
#region IServiceProvider Members
public object GetService(Type serviceType)
{
return serviceType == typeof(IWindowsFormsEditorService) ? this : null;
}
#endregion
#region ITypeDescriptorContext Members
IContainer ITypeDescriptorContext.Container
{
get { return null; }
}
object ITypeDescriptorContext.Instance
{
get { return component; }
}
void ITypeDescriptorContext.OnComponentChanged()
{}
bool ITypeDescriptorContext.OnComponentChanging()
{
return true;
}
PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
{
get { return property; }
}
#endregion
}
제휴하지 않습니다 StackOverflow