Hi.
I already invest a lot o time in doing a such thing for me. You have to
derive a new class from System.Windows.Forms.DataGridComboBoxColumn. Try
this code:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace RHSoft.UI
{
public class DataGridComboBoxColumn :
System.Windows.Forms.DataGridColumnStyle {
private System.Windows.Forms.ComboBox cboEdit;
private RHSoft.Data.Comparacoes.IComparable comparacao = null;
private System.Data.DataView view = null;
private bool blnLockEvent = false;
public DataGridComboBoxColumn() {
cboEdit = new System.Windows.Forms.ComboBox();
cboEdit.Visible = cboEdit.TabStop = false;
cboEdit.DropDownStyle = ComboBoxStyle.DropDownList;
cboEdit.DataSourceChanged += new EventHandler(EventComboDataSourceChanged);
cboEdit.SelectedIndexChanged += new
EventHandler(this.EventComboTextChanged);
}
public DataGridComboBoxColumn(System.Data.DataView view) : this() {
Init(view);
}
public void Init(System.Data.DataView view) {
this.view = view;
cboEdit.DataSource = this.view;
if (view.Table.Columns.Count > 0) {
if ((view.Count) > 0) {
comparacao =
RHSoft.Data.Comparacoes.IComparable.ConstructBasedOn(view[0][0].GetType(),
null);
}
else {
comparacao = new RHSoft.Data.Comparacoes.ComparableString(null);
}
//comparacao = (view.Count) > 0 ?
RHSoft.Data.Comparacoes.IComparable.ConstructBasedOn(view[0][0].GetType(),
null) : new RHSoft.Data.Comparacoes.ComparableString(null);
cboEdit.ValueMember = view.Table.Columns[0].ColumnName;
cboEdit.DisplayMember = view.Table.Columns[0].ColumnName;
}
}
protected override void ConcedeFocus() {
cboEdit.Hide();
}
protected override void Abort(int rowNum) {
}
// initiates a request to complete an editing procedure.
protected override bool Commit(System.Windows.Forms.CurrencyManager source,
int rowNum) {
cboEdit.Hide();
return true;
}
// Prepares the cell for editing a value.
protected override void Edit(System.Windows.Forms.CurrencyManager source,
int rowNum, Rectangle bounds, bool readOnly) {
}
// Prepares the cell for editing using the specified CurrencyManager, row
number, and Rectangle parameters.
protected override void Edit(System.Windows.Forms.CurrencyManager source,
int rowNum, Rectangle bounds, bool readOnly, string instantText) {
}
protected override void Edit(System.Windows.Forms.CurrencyManager source,
int rowNum, Rectangle bounds, bool readOnly, string instantText, bool
cellIsVisible) {
if (!cellIsVisible) {
cboEdit.Hide();
return;
}
try {
object valor = this.GetColumnValueAtRow(source, rowNum);
string strValue = valor.ToString();
blnLockEvent = true;
cboEdit.Enabled = !readOnly;
cboEdit.SetBounds(bounds.X, bounds.Y, bounds.Width, bounds.Height);
cboEdit.Show();
cboEdit.Focus();
cboEdit.SelectedValue = strValue;
if (cboEdit.SelectedIndex >= 0 && cboEdit.SelectedValue.ToString() !=
strValue) {
cboEdit.SelectedIndex = -1;
cboEdit.SelectedItem = null;
}
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}
finally {
blnLockEvent = false;
}
}
protected override int GetMinimumHeight() {
return 20;
}
protected override int GetPreferredHeight(Graphics g, object value) {
return this.DataGridTableStyle.PreferredRowHeight;
}
protected override Size GetPreferredSize(Graphics g, object value) {
return new Size(this.DataGridTableStyle.PreferredColumnWidth,
this.DataGridTableStyle.PreferredRowHeight);
}
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager
source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight) {
try {
g.FillRectangle(backBrush, bounds);
object data = this.GetColumnValueAtRow(source, rowNum);
if (data != System.DBNull.Value) {
if (cboEdit.ValueMember != cboEdit.DisplayMember) {
this.comparacao.Value = data;
int selectedIndex = RHSoft.Data.DataView.FindFirst(view, comparacao,
cboEdit.ValueMember);
if (selectedIndex >= 0)
data = view[selectedIndex][cboEdit.DisplayMember];
}
g.DrawString(data.ToString(), this.DataGridTableStyle.DataGrid.Font,
foreBrush, bounds.X, bounds.Y+2);
}
if (rowNum == this.DataGridTableStyle.DataGrid.CurrentRowIndex &&
this.DataGridTableStyle.GridColumnStyles.IndexOf(this) ==
this.DataGridTableStyle.DataGrid.CurrentCell.ColumnNumber) {
g.DrawRectangle(SystemPens.ControlDark, bounds.Left, bounds.Top,
bounds.Width-1, bounds.Height-1);
}
}
catch(Exception ex) {
g.DrawString(ex.Message, this.DataGridTableStyle.DataGrid.Font, foreBrush,
bounds.X, bounds.Y+2);
}
}
public bool IsOpen() {
return cboEdit.DroppedDown;
}
protected override void Paint(Graphics g, Rectangle bounds,
System.Windows.Forms.CurrencyManager source, int rowNum, bool alignToRight)
{
Paint(g, bounds, source, rowNum, new System.Drawing.SolidBrush(((rowNum % 2)
0) ? this.DataGridTableStyle.AlternatingBackColor :
this.DataGridTableStyle.BackColor),
System.Drawing.SystemBrushes.ControlText, alignToRight);
}
protected override void Paint(Graphics g, Rectangle bounds,
System.Windows.Forms.CurrencyManager source, int rowNum) {
Paint(g, bounds, source, rowNum, false);
}
protected override void SetDataGridInColumn(System.Windows.Forms.DataGrid
dataGrid) {
if (this.DataGridTableStyle != null &&
!this.DataGridTableStyle.DataGrid.Controls.Contains(cboEdit))
this.DataGridTableStyle.DataGrid.Controls.Add(cboEdit);
}
private void EventComboTextChanged(object sender, EventArgs e) {
if (blnLockEvent || !cboEdit.Focused ||
this.DataGridTableStyle.DataGrid.CurrentRowIndex < 0) {
return;
}
try {
if (cboEdit.SelectedItem == null) {
this.SetColumnValueAtRow((System.Windows.Forms.CurrencyManager)this.DataGrid
TableStyle.DataGrid.BindingContext[this.DataGridTableStyle.DataGrid.DataSour
ce], this.DataGridTableStyle.DataGrid.CurrentRowIndex, System.DBNull.Value);
}
else {
this.SetColumnValueAtRow((System.Windows.Forms.CurrencyManager)this.DataGrid
TableStyle.DataGrid.BindingContext[this.DataGridTableStyle.DataGrid.DataSour
ce], this.DataGridTableStyle.DataGrid.CurrentRowIndex,
cboEdit.SelectedValue);
}
bool dropped = this.cboEdit.DroppedDown;
object selectedItem = this.cboEdit.SelectedItem;
this.ColumnStartedEditing(cboEdit);
if (dropped && !this.cboEdit.DroppedDown) {
this.cboEdit.SelectedItem = selectedItem;
this.cboEdit.DroppedDown = true;
}
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}
}
private void EventComboDataSourceChanged(object sender, EventArgs e) {
if (cboEdit.DataSource is System.Data.DataTable) {
this.view = ((System.Data.DataTable)cboEdit.DataSource).DefaultView;
}
else {
this.view = (System.Data.DataView)cboEdit.DataSource;
}
if (view.Table.Columns.Count > 0) {
comparacao = (view.Count) > 0 ?
RHSoft.Data.Comparacoes.IComparable.ConstructBasedOn(view[0][0].GetType(),
null) : new RHSoft.Data.Comparacoes.ComparableString(null);
}
}
public System.Windows.Forms.ComboBox ComboBox {
get {
return cboEdit;
}
}
protected override void Dispose(bool disposing) {
base.Dispose (disposing);
cboEdit.DataSourceChanged -= new EventHandler(EventComboDataSourceChanged);
cboEdit.SelectedIndexChanged -= new
EventHandler(this.EventComboTextChanged);
if (view != null) {
view.Dispose();
}
if (disposing) {
cboEdit.Dispose();
cboEdit = null;
view = null;
comparacao = null;
}
}
}
}