2009-06-03 6 views
7

मेरे पास System.Data.DataRows कई फ़ील्ड के साथ हैं, उनमें से अधिकांश केवल int, एकल, स्ट्रिंग जैसे सादे प्रकार हैं।सी #/विनफॉर्म: एक संपत्तिग्रस्त और सिस्टम को सर्वोत्तम तरीके से कैसे बांधें। डेटा.डाटारो

एक संपत्तिग्रस्त का उपयोग करके संपादन योग्य बनाने का सबसे अच्छा तरीका क्या है? इसे स्वचालित रूप से काम करना चाहिए इससे कोई फर्क नहीं पड़ता कि डाटरो के किस तरह के फ़ील्ड हैं, लेकिन यह उन सभी को प्रदर्शित नहीं करना चाहिए। मैं उन गुणों की एक सूची प्रदान करना चाहता हूं जिन्हें छुपाया जाना चाहिए।

DataTable के बाद की तरह [ब्राउज़ करने योग्य (गलत)]

बहुत बहुत शुक्रिया विशेषताओं ऑटोजनरेटेड है मैं कस्टम नहीं जोड़ सकते हैं!

+0

बदले गए उदाहरण; अब स्तंभों को फ़िल्टर करने के लिए काम करता है –

उत्तर

14

संपादित छानने को संभालने के लिए; बहुत अधिक चालक: DataRowView प्राप्त करने के अलावा, हमें DataRowView (जो स्वयं DataRow होने का नाटक कर रहा है) होने के लिए (PropetyDescriptor एस के माध्यम से) के माध्यम से एक कस्टम घटक प्रदान करने की आवश्यकता है - और उन गुणों को फ़िल्टर करें जिन्हें हम नहीं करते हैं नहीं चाहता

बहुत दिलचस्प समस्या आसान ;-p क्लासिक कक्षाओं में हल करने के लिए, लेकिन नीचे के लिए DataRow ;-p

ध्यान दें कि आप इस क्षेत्र में अन्य बातों के कर सकता है गुण को भी संपादित नहीं से कुछ बनाने के लिए काम करता है (IsReadOnly), या RowWrapperDescriptor में अन्य सदस्यों को ओवरराइड करके एक अलग कैप्शन (DisplayName), या श्रेणी (Category) है।

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

ठीक है, धन्यवाद, लेकिन मैं इस दृश्य से कुछ गुण कैसे छिपा सकता हूं? उदाहरण के लिए मैं तालिका के "आईडी" को बदलना नहीं चाहता हूं। – clamp

+0

हम्म ... ट्रिकियर ... मुझे एक पल दें ... –

+0

धन्यवाद! Btw: के बाद से DataTable ऑटोजनरेटेड है मैं नहीं जोड़ सकते कस्टम की तरह विशेषताओं [ब्राउज़ करने योग्य (गलत)] – clamp

संबंधित मुद्दे