用datagrid中的模版列来实现

解决方案 »

  1.   

    public delegate void ComboValueChanged( int changingRow, object newValue );
    // Step 1. Derive a custom column style from DataGridTextBoxColumn
    // a) add a ComboBox member
    //  b) track when the combobox has focus in Enter and Leave events
    //  c) override Edit to allow the ComboBox to replace the TextBox
    //  d) override Commit to save the changed data
    public class DataGridComboBoxColumn : DataGridTextBoxColumn
    {
    public NoKeyUpCombo ColumnComboBox = null;
    private System.Windows.Forms.CurrencyManager _source = null;
    private int _rowNum;
    private bool _isEditing = false;
    ComboValueChanged _valueChanging;

    public DataGridComboBoxColumn(ComboValueChanged valueChanging) : base()
    {
    _valueChanging = valueChanging;
    ColumnComboBox = new NoKeyUpCombo();

    ColumnComboBox.Leave += new EventHandler(LeaveComboBox);
    // ColumnComboBox.Enter += new EventHandler(ComboMadeCurrent);
    ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged);
    ColumnComboBox.SelectionChangeCommitted += new System.EventHandler(ComboStartEditing);

    }

    private void ComboStartEditing(object sender, EventArgs e)
    {
    _isEditing = true;
    base.ColumnStartedEditing((Control) sender);
    }

    private void ComboIndexChanged(object sender, EventArgs e)
    {
    _valueChanging(_rowNum , ColumnComboBox.Text); 
    }// private void ComboMadeCurrent(object sender, EventArgs e)
    // {
    // //_isEditing = true; 
    // }

    private void LeaveComboBox(object sender, EventArgs e)
    {
    if(_isEditing)
    {
    SetColumnValueAtRow(_source, _rowNum, ColumnComboBox.Text);
    _isEditing = false;
    Invalidate();
    }
    ColumnComboBox.Hide();


    } protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
    {
    base.Edit(source,rowNum, bounds, readOnly, instantText , cellIsVisible); _rowNum = rowNum;
    _source = source;

    ColumnComboBox.Parent = this.TextBox.Parent;
    ColumnComboBox.Location = this.TextBox.Location;
    ColumnComboBox.Size = new Size(this.TextBox.Size.Width, ColumnComboBox.Size.Height);
    ColumnComboBox.SelectedIndexChanged -= new System.EventHandler(ComboIndexChanged);
    ColumnComboBox.Text =  this.TextBox.Text;
    ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged); this.TextBox.Visible = false;
    ColumnComboBox.Visible = true;
    ColumnComboBox.BringToFront();
    ColumnComboBox.Focus();
    } protected override bool Commit(System.Windows.Forms.CurrencyManager dataSource, int rowNum)
    {
    if(_isEditing)
    {
    _isEditing = false;
    SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text);
    }
    return true;
    }
    } public class NoKeyUpCombo : ComboBox
    {
    const int WM_KEYUP = 0x101;
    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
    if(m.Msg == WM_KEYUP)
    {
    //ignore keyup to avoid problem with tabbing & dropdownlist;
    return;
    }
    base.WndProc(ref m);
    }
    }