2009-06-03 21 views
7

'a en iyi şekilde nasıl bağlanırım System.Data.DataRows'ım var, bunların çoğu int, single, string gibi basit türlerde.C#/winforms: bir özellik kılavuzuna ve System.Data.DataRow

Onları bir propertygrid kullanarak düzenlenebilir hale getirmenin en iyi yolu nedir? , datarow'un ne tür alanları olursa olsun otomatik olarak çalışmalıdır, ancak bunların tümünü göstermemelidir. Gizlenmesi gereken özelliklerin listesini sağlamak istiyorum. DataTable beri

[Browsable (false)]

sayesinde çok gibi niteliklerini i ekleyemezsiniz autogenerated edilir!

+0

Örnek değiştirildi; şimdi, –

cevap

14

Filtrelemeyi işlemek için düzenlenmiş; çok tricker: DataRowView almak için ek olarak, DataRowView (DataRow gibi davranan bir pass-thru PropetyDescriptor s) aracılığıyla özel bir bileşen sağlamanız gerekir - ve biz don biz özellikleri istemiyorum.

Çok ilginç sorun klasik sınıflarda çözmek daha kolay ;-p, ancak aşağıda (düzenlenebilir olmayan bazı özelliklerini yapmak için bu alanda başka şeyler yapabilirdi DataRow ;-p

Not işleri (IsReadOnly) veya farklı bir altyazıya (DisplayName) veya kategori (Category) - RowWrapperDescriptor içinde diğer üyelerin geçersiz kılınmasını sağlayın.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Windows.Forms; 
static class program 
{ 
    [STAThread] 
    static void Main() 
    { 
     DataTable table = new DataTable(); 
     table.Columns.Add("ID", typeof(int)); 
     table.Columns.Add("Foo", typeof(int)); 
     table.Columns.Add("Bar", typeof(string)); 
     table.Columns.Add("Audit", typeof(DateTime)); 

     table.Rows.Add(1, 14, "abc", DateTime.MinValue); 
     DataRow row = table.Rows.Add(2,13,"def", DateTime.MinValue); 
     table.Rows.Add(3, 24, "ghi", DateTime.MinValue); 

     RowWrapper wrapper = new RowWrapper(row); 
     wrapper.Exclude.Add("ID"); 
     wrapper.Exclude.Add("Bar"); 

     Application.EnableVisualStyles(); 
     Application.Run(new Form {Controls = { 
      new PropertyGrid { Dock = DockStyle.Fill, 
       SelectedObject = wrapper}}}); 
    } 
} 

[TypeConverter(typeof(RowWrapper.RowWrapperConverter))] 
class RowWrapper 
{ 
    private readonly List<string> exclude = new List<string>(); 
    public List<string> Exclude { get { return exclude; } } 
    private readonly DataRowView rowView; 
    public RowWrapper(DataRow row) 
    { 
     DataView view = new DataView(row.Table); 
     foreach (DataRowView tmp in view) 
     { 
      if (tmp.Row == row) 
      { 
       rowView = tmp; 
       break; 
      } 
     } 
    } 
    static DataRowView GetRowView(object component) 
    { 
     return ((RowWrapper)component).rowView; 
    } 
    class RowWrapperConverter : TypeConverter 
    { 
     public override bool GetPropertiesSupported(ITypeDescriptorContext context) 
     { 
      return true; 
     } 
     public override PropertyDescriptorCollection GetProperties(
      ITypeDescriptorContext context, object value, Attribute[] attributes) 
     { 
      RowWrapper rw = (RowWrapper)value; 
      PropertyDescriptorCollection props = TypeDescriptor.GetProperties(
       GetRowView(value), attributes); 
      List<PropertyDescriptor> result = new List<PropertyDescriptor>(props.Count); 
      foreach (PropertyDescriptor prop in props) 
      { 
       if (rw.Exclude.Contains(prop.Name)) continue; 
       result.Add(new RowWrapperDescriptor(prop)); 
      } 
      return new PropertyDescriptorCollection(result.ToArray()); 
     } 
    } 
    class RowWrapperDescriptor : PropertyDescriptor 
    { 
     static Attribute[] GetAttribs(AttributeCollection value) 
     { 
      if (value == null) return null; 
      Attribute[] result = new Attribute[value.Count]; 
      value.CopyTo(result, 0); 
      return result; 
     } 
     readonly PropertyDescriptor innerProp; 
     public RowWrapperDescriptor(PropertyDescriptor innerProperty) 
      : base(
       innerProperty.Name, GetAttribs(innerProperty.Attributes)) 
     { 
      this.innerProp = innerProperty; 
     } 


     public override bool ShouldSerializeValue(object component) 
     { 
      return innerProp.ShouldSerializeValue(GetRowView(component)); 
     } 
     public override void ResetValue(object component) 
     { 
      innerProp.ResetValue(GetRowView(component)); 
     } 
     public override bool CanResetValue(object component) 
     { 
      return innerProp.CanResetValue(GetRowView(component)); 
     } 
     public override void SetValue(object component, object value) 
     { 
      innerProp.SetValue(GetRowView(component), value); 
     } 
     public override object GetValue(object component) 
     { 
      return innerProp.GetValue(GetRowView(component)); 
     } 
     public override Type PropertyType 
     { 
      get { return innerProp.PropertyType; } 
     } 
     public override Type ComponentType 
     { 
      get { return typeof(RowWrapper); } 
     } 
     public override bool IsReadOnly 
     { 
      get { return innerProp.IsReadOnly; } 
     } 
    } 
} 
+0

sütunlarını filtrelemek için çalışıyor, teşekkürler, ancak bu görünümden belirli özellikleri nasıl gizleyebilirim? örneğin, tablonun "Id" değerinin değiştirilmesini istemiyorum. – clamp

+0

Hmmm ... trickier ... bana bir dakika ver ... –

+0

teşekkür ederim! btw: DataTable otomatik olarak oluşturulduğundan, [Browsable (false)] – clamp