2009-01-23 23 views
5

Tôi có một PropertyGrid trên biểu mẫu của mình. Ông chủ của tôi nghĩ rằng nó xấu xí. Uncouth. Không phức tạp.Sử dụng trình chỉnh sửa bộ sưu tập .NET mà không sử dụng điều khiển lưới thuộc tính

Anh ấy muốn hình thức đẹp, gọn gàng, sạch sẽ. Đây là bắt: Một trong những thuộc tính là một bộ sưu tập của các đối tượng nhà trồng của chúng tôi. Anh ấy thích trình chỉnh sửa bộ sưu tập cho bộ sưu tập này.

Tôi biết tôi có thể tạo trình chỉnh sửa bộ sưu tập của riêng mình. Nhưng có một giải pháp đơn giản, sạch sẽ để tiết kiệm cho tôi một vài giờ mã hóa, sao cho tôi có thể tạo và sử dụng trình chỉnh sửa Bộ sưu tập trực tiếp mà không cần sử dụng lưới thuộc tính?

Trả lời

10

Bạn có thể có được chức năng này từ UITypeEditor (thông qua TypeDescriptor), nhưng nó không phải là tầm thường - bạn cần phải thiết lập một IServiceProvider, một IWindowsFormsEditorService, và lý tưởng một ITypeDescriptorContext - khá nhiều faff. Nó có thể đơn giản hơn để làm điều đó bằng tay nếu bạn không quen thuộc với những công cụ đó.

Cách khác - hãy xem SmartPropertyGrid.NET, thay thế cho PropertyGrid.


Cập nhật: đây là ví dụ hoạt động ... chắc chắn không tầm thường, nhưng cảm thấy tự do để lấy cắp mã. Nó chỉ hoạt động cho các trình soạn thảo phương thức, không phải trình đơn thả xuống. Nó cũng không phải là một ví dụ tuyệt vời của "tách mối quan tâm". Lớp học MyHelper là một lớp học thú vị.

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 
} 
+0

Không đùa đâu! Tôi bắt đầu đặt cùng một mẫu (tôi đã làm một cái gì đó tương tự như điều này trong quá khứ), và nó đã ra khỏi tầm kiểm soát khá nhanh. –

Các vấn đề liên quan