2011-11-20 130 views
0

我设法将另一列添加到DGV,但现在我无法用值填充单元格。如何填充DataGridView中的自定义列单元格

这是我到目前为止有:

// add new column 
int lineItemsColumnIndex = dataGridView1.Columns.Add("LineItems", "Line Items"); 

// set up nested DataGridView for orders and lineitems. 
foreach (DataGridViewRow row in dataGridView1.Rows) 
{ 
    List<LineItem> lineItems = ((Order)(row.DataBoundItem)).lineItems; 
    string cellValue = ""; 
    for(int i=0; i<lineItems.Count; i++){ 
     FoodMenuItem menuItem = new FoodMenuItem(lineItems[i].menuItemID); 
     cellValue += lineItems[i].quantity.ToString() + "x " + menuItem.title + (i==lineItems.Count-1 ? "." : ", "); 
    } 
    row.Cells[lineItemsColumnIndex].Value = cellValue; 
} 

如何把数据放到自定义列?

回答

0

它应该工作的方式......

你确定了DGV已经有行代码运行时?

但你能想到另一件事:

,你可以为你的数据对象的包装,和/或添加自定义typedescriptor,到一个新的属性添加到您的数据能够被使用。净绑定,所以你就不必手动设置列...

是这样的:

public class Wrapper<T> : System.ComponentModel.ICustomTypeDescriptor 
    { 
     public T wrappee { get; private set; } 
     private Dictionary<String, Func<T, String>> ext_get; 
     public Wrapper(T theObjectWeWantToWrap,Dictionary<String,Func<T,String>> theSpecsForTheAdditionalColumns) 
     { 
      wrappee = theObjectWeWantToWrap; 
      ext_get = theSpecsForTheAdditionalColumns; 
     } 

     System.ComponentModel.AttributeCollection System.ComponentModel.ICustomTypeDescriptor.GetAttributes() 
     { 
      return TypeDescriptor.GetAttributes(wrappee,true); 
     } 

     string System.ComponentModel.ICustomTypeDescriptor.GetClassName() 
     { 
      return TypeDescriptor.GetClassName(wrappee, true); 
     } 

     string System.ComponentModel.ICustomTypeDescriptor.GetComponentName() 
     { 
      return TypeDescriptor.GetComponentName(wrappee, true); 
     } 

     System.ComponentModel.TypeConverter System.ComponentModel.ICustomTypeDescriptor.GetConverter() 
     { 
      return TypeDescriptor.GetConverter(wrappee, true); 
     } 

     System.ComponentModel.EventDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultEvent() 
     { 
      return TypeDescriptor.GetDefaultEvent(wrappee, true); 
     } 

     System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() 
     { 
      return TypeDescriptor.GetDefaultProperty(wrappee, true); 
     } 

     object System.ComponentModel.ICustomTypeDescriptor.GetEditor(Type editorBaseType) 
     { 
      return TypeDescriptor.GetEditor(wrappee, editorBaseType, true); 
     } 

     System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(Attribute[] attributes) 
     { 
      return TypeDescriptor.GetEvents(wrappee, attributes, true); 
     } 

     System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() 
     { 
      return TypeDescriptor.GetEvents(wrappee, true); 
     } 

     System.ComponentModel.PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties(Attribute[] attributes) 
     { 
      return filterProps(TypeDescriptor.GetProperties(wrappee, attributes, true)); 
     } 

     System.ComponentModel.PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties() 
     { 
      return filterProps(TypeDescriptor.GetProperties(wrappee, true)); 
     } 

     object System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(System.ComponentModel.PropertyDescriptor pd) 
     { 
      if (ext_get.Keys.Contains(pd.Name)) 
       return this; 
      return wrappee; 
     } 

     private PropertyDescriptorCollection filterProps(PropertyDescriptorCollection propertyDescriptorCollection) 
     { 
      List<PropertyDescriptor> pd_list = new List<PropertyDescriptor>(propertyDescriptorCollection.Cast<PropertyDescriptor>().Where(x=>!ext_get.Keys.Contains(x.DisplayName))); 
      foreach (var item in ext_get) 
      { 
       pd_list.Add(new MyPropertyDescriptor<T>(item)); 
      } 
      return new PropertyDescriptorCollection(pd_list.ToArray()); 
     } 
     private class MyPropertyDescriptor<T> : System.ComponentModel.PropertyDescriptor 
     { 
      public MyPropertyDescriptor(KeyValuePair<string,Func<T,string>>kvp) 
       :base(kvp.Key,new Attribute[]{}) 
      { 
       f = kvp.Value; 
      } 
      private Func<T, String> f; 

      public override bool CanResetValue(object component) 
      { 
       return false; 
      } 

      public override Type ComponentType 
      { 
       get { return typeof(Wrapper<T>); } 
      } 

      public override object GetValue(object component) 
      { 
       Wrapper<T> c = (Wrapper<T>)component; 
       return f(c.wrappee); 
      } 

      public override bool IsReadOnly 
      { 
       get { return true; } 
      } 

      public override Type PropertyType 
      { 
       get { return typeof(String); } 
      } 

      public override void ResetValue(object component) 
      { 
       throw new NotImplementedException(); 
      } 

      public override void SetValue(object component, object value) 
      { 
       throw new NotImplementedException(); 
      } 

      public override bool ShouldSerializeValue(object component) 
      { 
       return false; 
      } 
     } 
    } 

,然后可以像这样使用:

List<DataClass> list = new List<DataClass>(); 
    list.Add(new DataClass()); 

    Dictionary<string, Func<DataClass, String>> ext = new Dictionary<string, Func<DataClass, string>>(); 

    ext["New Column"] = (DataClass x) => String.Join(" ,", x.Items.ToArray()); 

    List<Wrapper<DataClass>> list2 = new List<Wrapper<DataClass>>(list.Select(x=>new Wrapper<DataClass>(x,ext))); 
    class1DataGridView.DataSource = list2; 
0

您添加列,在DataBindingComplete事后做这样的事情:

foreach (DataGridViewRow row in dgv.Rows) 
{if (row.Cells[7].Value.ToString()=="1") 
row.Cells[0].Value = "number one"; } 

(只是个愚蠢的例子来说明)

但请记住它必须是在DataBindingComplete(或者从按钮点击等),否则它将保持空白

相关问题