2009-01-23 9 views
5

J'ai un PropertyGrid sur mon formulaire. Mon patron pense que c'est moche. Grossier. Simple.Utilisation de l'éditeur de collection .NET sans utiliser un contrôle de grille de propriétés

Il veut une belle forme nette et propre. Voici la capture: Une des propriétés est une collection de nos objets cultivés à la maison. Il aime l'éditeur de collection pour cette collection. Je sais que je peux créer mon propre éditeur de collection. Mais existe-t-il une solution propre et simple pour me sauver quelques heures de codage, de sorte que je puisse créer et utiliser directement un éditeur de collection sans utiliser la grille de propriétés?

Répondre

10

Vous pouvez obtenir cette fonctionnalité du UITypeEditor (via TypeDescriptor), mais ce n'est pas trivial - vous avez besoin de mettre en place un IServiceProvider, un IWindowsFormsEditorService, et idéalement un ITypeDescriptorContext - un peu de faff. Il pourrait être plus simple de le faire à la main si vous n'êtes pas familier avec ces outils.

Alternativement - jetez un oeil à SmartPropertyGrid.NET, une alternative à PropertyGrid. Mise à jour: voici un exemple de travail ... définitivement non-trivial, mais n'hésitez pas à voler le code. Cela ne fonctionne que pour les éditeurs modaux, pas de liste déroulante. Ce n'est pas non plus un bon exemple de «séparation des préoccupations». La classe MyHelper est intéressante.

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

Sans blague! J'ai commencé à rassembler un échantillon (j'ai déjà fait quelque chose de similaire dans le passé), et il est devenu incontrôlable. –

Questions connexes