class  DataGridComboBoxColumn: DataGridColumnStyle  
     { 
         private ComboBox myComboBox = new ComboBox (); 
         private DataView ChoiceDataViewSource; 
         private string ChoiceDisplayField; 
         private string ChoiceValueField; 
         private bool isEditing; 
  
         public DataGridComboBoxColumn(DataView ChoiceDataViewSource,string ChoiceDisplayField,string ChoiceValueField) : base()  
         { 
             this.ChoiceDataViewSource =ChoiceDataViewSource; 
             this.ChoiceDisplayField =ChoiceDisplayField; 
             this.ChoiceValueField =ChoiceValueField; 
             myComboBox.DropDownStyle =System.Windows .Forms .ComboBoxStyle .DropDownList  ; 
             myComboBox.Visible = false; 
             myComboBox.DataSource =this.ChoiceDataViewSource; 
             myComboBox.DisplayMember= this.ChoiceDisplayField; 
             myComboBox.ValueMember =this.ChoiceValueField; 
         } 
         protected override void Abort(int rowNum) 
         { 
             isEditing = false; 
             myComboBox.SelectedIndexChanged -=  
                 new EventHandler(ComboBoxSelectedIndexChanged ); 
             Invalidate(); 
         } 
  
         protected override bool Commit 
             (CurrencyManager dataSource, int rowNum)  
         { 
             myComboBox.Bounds = Rectangle.Empty; 
           
             myComboBox.SelectedIndexChanged -=  
                 new EventHandler(ComboBoxSelectedIndexChanged ); 
  
             if (!isEditing) 
                 return true; 
  
             isEditing = false; 
  
             try  
             { 
                 System.Object  value = myComboBox.SelectedValue; 
                 SetColumnValueAtRow(dataSource, rowNum, value); 
             }  
             catch (Exception)  
             { 
                 Abort(rowNum); 
                 return false; 
             } 
  
             Invalidate(); 
             return true; 
         } 
  
         protected override void Edit( 
             CurrencyManager source,  
             int rowNum, 
             Rectangle bounds,  
             bool readOnly, 
             string instantText,  
             bool cellIsVisible)  
         { 
             object value =GetColumnValueAtRow(source, rowNum); 
             if (cellIsVisible)  
             { 
                 myComboBox.Bounds = new Rectangle 
                     (bounds.X + 2, bounds.Y + 2,  
                     bounds.Width - 4, bounds.Height - 4); 
                 int i=    Find (value); 
                 if (myComboBox.Items .Count >i)  
                 { 
                     myComboBox.SelectedIndex =i; 
                 } 
                 myComboBox.Visible = true; 
                 myComboBox.SelectedIndexChanged +=  
                     new EventHandler(ComboBoxSelectedIndexChanged ); 
             }  
             else  
             { 
                 myComboBox.SelectedIndex =this.Find (value); 
                 myComboBox.Visible = false; 
             } 
             if (myComboBox.Visible) 
                 DataGridTableStyle.DataGrid.Invalidate(bounds); 
         } 
         protected int Find(System.Object value) 
         { 
             int int1; 
             int int2; 
              
             int2=ChoiceDataViewSource.Count ; 
             if (int2<=0) 
             { 
                 return -1; 
             } 
             for (int1=0;int1<int2;int1++) 
             { 
                 if (ChoiceDataViewSource[int1][this.myComboBox .ValueMember ].ToString ().Trim ()==value.ToString ().Trim ()) 
                 { 
                     return int1; 
                 } 
             } 
             return -1; 
         } 
  
         protected override Size GetPreferredSize( 
             Graphics g,  
             object value)  
         { 
             return new Size(100, myComboBox.PreferredHeight+ 4); 
         } 
  
         protected override int GetMinimumHeight()  
         { 
             return myComboBox.PreferredHeight + 4; 
         } 
  
         protected override int GetPreferredHeight(Graphics g,  
             object value)  
         { 
             return myComboBox.PreferredHeight + 4; 
         } 
  
         protected override void Paint(Graphics g,  
             Rectangle bounds,  
             CurrencyManager source,  
             int rowNum)  
         { 
             Paint(g, bounds, source, rowNum, false); 
         } 
         protected override void Paint( 
             Graphics g,  
             Rectangle bounds, 
             CurrencyManager source,  
             int rowNum, 
             bool alignToRight)  
         { 
             Paint( 
                 g,bounds,  
                 source,  
                 rowNum,  
                 ,  
                 Brushes.Blue,  
                 alignToRight); 
         } 
         protected override void Paint( 
             Graphics g,  
             Rectangle bounds, 
             CurrencyManager source,  
             int rowNum, 
             Brush backBrush,  
             Brush foreBrush, 
             bool alignToRight)  
         { 
             object value=GetColumnValueAtRow(source, rowNum); 
             int int1=Find (value); 
             string display=""; 
             if (int1>=0) 
             { 
                 display=this.ChoiceDataViewSource [int1][this.myComboBox .DisplayMember ].ToString (); 
             } 
             Rectangle rect = bounds; 
             g.FillRectangle(backBrush,rect); 
             rect.Offset(0, 2); 
             rect.Height -= 2; 
             g.DrawString(display,  
                 this.DataGridTableStyle.DataGrid.Font,  
                 foreBrush, rect); 
         } 
  
         protected override void SetDataGridInColumn(DataGrid value)  
         { 
             base.SetDataGridInColumn(value); 
             if (myComboBox.Parent != null)  
             { 
                 myComboBox.Parent.Controls.Remove  
                     (myComboBox); 
             } 
             if (value != null)  
             { 
                 value.Controls.Add(myComboBox); 
             } 
         } 
  
         private void ComboBoxSelectedIndexChanged(object sender, EventArgs e)  
         { 
             this.isEditing = true; 
             base.ColumnStartedEditing(myComboBox); 
         } 
     }
  使用例: 
     表T1(学生档案)    学生ID(主键)  
                                         班级ID_Point 
                                        学生姓名 
     表T2(班级档案)     班级ID(主键) 
                                       班级名称 
     T1.班级ID_Point=T2.班级ID 
     在datagrid显示学生档案时要同时显示班级名称,并可使用下拉列表调整学生所属班级。datagrid的班级ID列可使用DataGridComboBoxColumn列样式。datagrid的DataGridComboBoxColumn(班级ID)列需单独传递班级档案数据源(T2的dataview),显示的字段名称(班级名称),值字段名称(班级ID)。datagrid生成时先生成各列DataGridColumnStyle(遇到DataGridComboBoxColumn时,load班级档案数据并传参),再生成DataGridTableStyle,将各DataGridColumnStyle加入到DataGridTableStyle,最后将DataGridTableStyle加入到datagrid。 
 
 
                     
            
        













 
                    

 
                 
                    