[WinForm] DataGrid中的ComboBox下拉框

我在网上发现的一个类,没看到出处,希望作者看到见谅,它从DataGridColumnStyle所继承

原类在增加新行时出错,出错原因是未将新行值写到绑定管理器(CurrencyManager)里面去

修改的部分我列了出来。

参考资料:

1.关于WinForm.DataGrid的一个好FAQ

http://www.syncfusion.com/FAQ/WinForms/FAQ_c44c.asp#q480q

2.CodeProject  和 C#-Corner

http://www.codeproject.com/cs/miscctrl/DataGridZen.asp?df=100&forumid=31224&exp=0&select=715228

http://www.codeproject.com/cs/miscctrl/RenDataGridComboBoxColumn.asp

http://www.c-sharpcorner.com/winforms/ComboBoxInDataGridSKJ.asp

3.MSDN and CSDN

 

using System;
using System.Data;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;

namespace ComboBoxInDataGrid
{
 /// <summary>
 /// Implementation of a ComboBox as a column in a DataGrid
 /// </summary>
 public class DataGridComboBoxColumn : DataGridColumnStyle
 {
  private int _xMargin = 1;
  private int _yMargin = 0;
  private ComboBox _comboBox;
  private string _oldValue="";
  private bool _inEdit= false;
  private DataTable _dataTable;
  private string _displayMember, _valueMember;
  
  //增加了两个成员变量,保存Edit事件发生时的数据

  private CurrencyManager _cm;
  private int _iRowNum;

  /// <summary>
  /// The only creator ;)
  /// </summary>
  /// <param name="colName">The name of the column</param>
  /// <param name="dataSource">The datasource that contains the lookup table</param>
  /// <param name="displayMember">The member of the lookuptable to display</param>
  /// <param name="valueMember">The member of the lookuptable with the value</param>
  /// <param name="dataGrid">The datagrid parent of this column</param>
  public DataGridComboBoxColumn(string colName, DataTable dataSource, string displayMember, string valueMember, DataGrid dataGrid)
  {
   _comboBox = new ComboBox();
   _comboBox.Visible = false;
   _comboBox.DataSource = dataSource;
   _dataTable = dataSource;
   _comboBox.DisplayMember = displayMember;
   _displayMember=displayMember;
   _valueMember=valueMember;
   _comboBox.ValueMember = valueMember;
   _comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
   Graphics _graphicsContext=dataGrid.CreateGraphics();
   float _widest=0;
   SizeF _stringSize=new SizeF(0,0);
   foreach (DataRow dr in dataSource.Rows)
   {
    _stringSize=_graphicsContext.MeasureString(dr[displayMember].ToString(), dataGrid.Font);
    if (_stringSize.Width>_widest)
    {
     _widest=_stringSize.Width;
    }
   }
   _comboBox.DropDownWidth=(int)Math.Ceiling(_widest);
   this.Width=_comboBox.DropDownWidth+25; // Add the space for the dropdown arrow
   this.MappingName=colName;
   this.HeaderText=colName;
   

//增加了一个ComboBox.Leave事件,适时的将值写到绑定管理其中
            this._comboBox.Leave+=new EventHandler(_comboBox_Leave);

   dataGrid.Controls.Clear();
   dataGrid.Controls.Add(_comboBox);
  }

  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="rowNum"></param>
  protected override void Abort(int rowNum)
  {
   _inEdit=false;
   _comboBox.Hide();
  }
  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="dataSource"></param>
  /// <param name="rowNum"></param>
  /// <returns></returns>
  protected override bool Commit(CurrencyManager dataSource,int rowNum)
  {
   if(!_inEdit)
   {
    return true;
   }
   try
   {
    object _value = _comboBox.SelectedValue;
    if(NullText.Equals(_value))
    {
     _value = System.Convert.DBNull;
    }
    this.SetColumnValueAtRow(dataSource, rowNum, _value);
   }
   catch
   {
    return false;
   }
   finally
   {
    _inEdit=false;
    _comboBox.Hide();
   }
   return true;
  }
  
  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="source"></param>
  /// <param name="rowNum"></param>
  /// <param name="bounds"></param>
  /// <param name="readOnly"></param>
  /// <param name="instantText"></param>
  /// <param name="cellIsVisible"></param>
  protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
  {
   _comboBox.Text = "";
   Rectangle _originalBounds = bounds;
   _oldValue = _comboBox.Text;
 

//记录绑定管理器和行号

   this._cm=source;
   this._iRowNum=rowNum;

   if(!cellIsVisible) return;

   bounds.Offset(_xMargin, _yMargin);
   bounds.Width -= _xMargin * 2;
   bounds.Height -= _yMargin;
   _comboBox.Bounds = bounds;
   _comboBox.Visible = true;
   //_comboBox.BringToFront();
   //_comboBox.Focus();
   if(System.DBNull.Value==GetColumnValueAtRow(source, rowNum))
   {
    MessageBox.Show("你点的单元格是空值");
   }
   else
   {
    _comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
   
    if(instantText!=null)
    {
     _comboBox.SelectedValue = instantText;
     int End = _comboBox.Text.Length;
     _comboBox.Select(End, 0);
    }
    else
    {
     _comboBox.SelectAll();
    }
   }
   //this.DataGridTableStyle.DataGrid.Invalidate(OriginalBounds);
   //_comboBox.BringToFront();
   _inEdit = true;

  }
  
  /// <summary>
  /// Standard override
  /// </summary>
  /// <returns></returns>
  protected override int GetMinimumHeight()
  {
   return _comboBox.PreferredHeight + _yMargin;
  }
  
  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="g"></param>
  /// <param name="val"></param>
  /// <returns></returns>
  protected override int GetPreferredHeight(Graphics g ,object val)
  {
   return FontHeight + _yMargin;
  }
  
  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="g"></param>
  /// <param name="val"></param>
  /// <returns></returns>
  protected override Size GetPreferredSize(Graphics g, object val)
  {
   Size _extents = Size.Ceiling(g.MeasureString(GetText(val), this.DataGridTableStyle.DataGrid.Font));
   _extents.Width += _xMargin * 2 ;
   _extents.Height += _yMargin;
   return _extents;
  }
  
  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="g"></param>
  /// <param name="bounds"></param>
  /// <param name="source"></param>
  /// <param name="rowNum"></param>
  protected override void Paint(Graphics g,Rectangle bounds,CurrencyManager source,int rowNum)
  {
   Paint(g, bounds, source, rowNum, false);
  }

  /// <summary>
  /// Standard override
  /// </summary>
  /// <param name="g"></param>
  /// <param name="bounds"></param>
  /// <param name="source"></param>
  /// <param name="rowNum"></param>
  /// <param name="alignToRight"></param>
  protected override void Paint(Graphics g,Rectangle bounds,CurrencyManager source,int rowNum, bool alignToRight)
  {
   string _text = GetText(GetColumnValueAtRow(source, rowNum));
   foreach (DataRow dr in _dataTable.Rows)
   {
    if (dr[_valueMember].ToString()==_text)
    {
     _text=dr[_displayMember].ToString();
     break;
    }
   }
   PaintText(g, bounds, _text, alignToRight);
  }

  // Helper functions
  private void PaintText(Graphics g ,Rectangle bounds, string text,bool alignToRight)
  {
   Brush _backBrush = new SolidBrush(this.DataGridTableStyle.BackColor);
   Brush _foreBrush= new SolidBrush(this.DataGridTableStyle.ForeColor);
   Rectangle _rect = bounds;
   RectangleF _rectF  = _rect;
   StringFormat _format = new StringFormat();
   if(alignToRight)
   {
    _format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
   }
   switch(this.Alignment)
   {
    case HorizontalAlignment.Left:
     _format.Alignment = StringAlignment.Near;
     break;
    case HorizontalAlignment.Right:
     _format.Alignment = StringAlignment.Far;
     break;
    case HorizontalAlignment.Center:
     _format.Alignment = StringAlignment.Center;
     break;
   }
   _format.FormatFlags =StringFormatFlags.NoWrap;
   g.FillRectangle(_backBrush, _rect);
   _rect.Offset(0, _yMargin);
   _rect.Height -= _yMargin;
   g.DrawString(text, this.DataGridTableStyle.DataGrid.Font, _foreBrush, _rectF, _format);
   _format.Dispose();
  }

  private string GetText(object val)
  {
   if(val==System.DBNull.Value)
   {
    return this.NullText;
   }
   if(val!=null)
   {
    return val.ToString();
   }
   else
   {
    return string.Empty;
   }
  }

//当焦点从ComboBox离开时,将ComboBox中的值写回绑定管理器,并将ComboBox不可见  

private void _comboBox_Leave(object sender, EventArgs e)
  {
   object objValue=this._comboBox.SelectedValue;
   if(objValue==null)
   {
    objValue = DBNull.Value;
   }
   this.SetColumnValueAtRow(this._cm,this._iRowNum,objValue);
   this._comboBox.Visible=false;
  }
 }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值