2009-06-03 1 views
7

のC#/リサイズ:私はいくつかのフィールド、int型、シングル、紐のようなそれらのほとんど単なるタイプとSystem.Data.DataRowsを持って最善の方法PropertyGridのをバインドするとSystem.Data.DataRow

プロパティグリッドを使って編集できるようにするにはどうすればよいですか? データローのフィールドの種類に関係なく自動的に動作するはずですが、それらのすべてを表示するべきではありません。私は隠されるべきプロパティのリストを提供したい。

のDataTableには、私はカスタム[ブラウズ可能(偽)]などの属性

おかげで多くを追加することはできません自動生成されているので!

+0

変更例;今すぐ列をフィルタリングするために動作します –

答えて

14

フィルタリングを処理するように編集されました。多くのトリッカー:DataRowViewを得ることに加えて、(PropetyDescriptorをパススルーとして)DataRowView(それ自体はDataRowであると思われる)を装うカスタムコンポーネントを提供する必要があります。欲しい。

非常に興味深い問題は、古典的なクラスに解決するために簡単;-pが、以下(あなたが編集不可能なプロパティの一部を作るために、この領域に他のことを行うことができDataRow ;-p

注意のために働きますIsReadOnly)、または別のキャプション(DisplayName)、またはカテゴリ(Category) - RowWrapperDescriptorの他のメンバーを上書きしてください。

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

ありがとう、しかし、私はこのビューから特定のプロパティを隠すことができますか?たとえば、私はテーブルの "Id"を変更したくないです。 – clamp

+0

Hmmm ...トリッキーな...私に瞬間を与える... –

+0

ありがとう! btw:DataTableが自動生成されているため、[Browsable(false)]のようなカスタム属性を追加できません。 – clamp

関連する問題