2012-06-21 10 views
15

Mam DataGridView z dwiema kolumnami. Pierwsza kolumna to TextBoxCol(DataGridViewTextBoxColumn), a druga to ComboBoxCol(DataGridViewComboBoxColumn).Zdarzenie uruchamiane podczas DataGridViewComboBoxColumn SelectedIndexChanged

Jak zmienić wartość TextBoxCol, gdy ComboBoxCol zmienia wybraną wartość indeksu? (To powinno się zdarzyć, gdy wybrany indeks zmienił w ComboBoxCol. Nie po opuszczeniu kolumny, jak dataGridView_CellValueChanged)

Czytałem jeden temat z niemal tego samego problemu, który mam, ale ja nie rozumiem odpowiedź (która powinna być prawidłowa opierać się na znaczniku wyboru). Oto link. -Almost same topic

+0

Cieszę się, że mogę pomóc, będę mieć oko na więcej pytań, ponieważ już mam projekt otwarty :). – KreepN

+1

Możliwy duplikat [Jakie wydarzenie przechwytuje zmianę wartości w combobox w DataGridViewCell?] (Http://stackoverflow.com/questions/5652957/what-event-catches-a-change-of-value-in-a -combobox-in-a-datagridviewcell) –

Odpowiedz

23

Daj te dwa proste metody odchodzenie (tzw 1 "w górnej metodzie jest indeks kolumny combobox)

Wiersz, w którym dokonasz modyfikacji, będzie linia ustawiająca cel.Value =, ponieważ możesz ją zmienić na dowolną.


private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
    { 
     if (dataGridView1.CurrentCell.ColumnIndex == 1 && e.Control is ComboBox) 
     { 
      ComboBox comboBox = e.Control as ComboBox; 
      comboBox.SelectedIndexChanged -= LastColumnComboSelectionChanged; 
      comboBox.SelectedIndexChanged += LastColumnComboSelectionChanged; 
     } 
    } 

    private void LastColumnComboSelectionChanged(object sender, EventArgs e) 
    { 
     var currentcell = dataGridView1.CurrentCellAddress; 
     var sendingCB = sender as DataGridViewComboBoxEditingControl; 
     DataGridViewTextBoxCell cel = (DataGridViewTextBoxCell)dataGridView1.Rows[currentcell.Y].Cells[0]; 
     cel.Value = sendingCB.EditingControlFormattedValue.ToString(); 
    } 

enter image description here

+8

Upewnij się, że usuniesz także wszystkie istniejące procedury obsługi zdarzeń za pomocą komendy 'comboBox.SelectedIndexChanged - = LastColumnComboSelectionChanged;' – Smashery

2

To połączenie jest poprawne. Obsługiwać EditingControlShowing event DataGridView. W tym module obsługi zdarzeń sprawdź, czy aktualna kolumna jest dla Ciebie interesująca. A następnie utworzyć tymczasowy obiekt combobox: -

ComboBox comboBox = e.Control as ComboBox;

MSDN ma próbki: patrz w sekcji przykładów here. ZanotujInheritance Hierarchy & Class Syntax w linku MSDN: -

public class DataGridViewComboBoxEditingControl: ComboBox, IDataGridViewEditingControl

private DataGridView dataGridView1 = new DataGridView(); 

private void AddColorColumn() 
{ 
    DataGridViewComboBoxColumn comboBoxColumn = 
     new DataGridViewComboBoxColumn(); 
    comboBoxColumn.Items.AddRange(
     Color.Red, Color.Yellow, Color.Green, Color.Blue); 
    comboBoxColumn.ValueType = typeof(Color); 
    dataGridView1.Columns.Add(comboBoxColumn); 
    dataGridView1.EditingControlShowing += 
     new DataGridViewEditingControlShowingEventHandler(
     dataGridView1_EditingControlShowing); 
} 

private void dataGridView1_EditingControlShowing(object sender, 
    DataGridViewEditingControlShowingEventArgs e) 
{ 
    ComboBox combo = e.Control as ComboBox; 
    if (combo != null) 
    { 
     // Remove an existing event-handler, if present, to avoid 
     // adding multiple handlers when the editing control is reused. 
     combo.SelectedIndexChanged -= 
      new EventHandler(ComboBox_SelectedIndexChanged); 

     // Add the event handler. 
     combo.SelectedIndexChanged += 
      new EventHandler(ComboBox_SelectedIndexChanged); 
    } 
} 

private void ComboBox_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    ((ComboBox)sender).BackColor = (Color)((ComboBox)sender).SelectedItem; 
} 
28

Ta odpowiedź jest pływających wokół w kilku miejscach. Użycie obiektu DataGridViewEditingControlShowingEventHandler spowoduje uruchomienie większej liczby zdarzeń, niż zamierzano. Podczas mojego testowania wielokrotnie uruchamiał to wydarzenie. Również użycie zdarzenia combo.SelectedIndexChanged - = naprawdę nie usunie zdarzenia, po prostu dalej się układają. W każdym razie znalazłem rozwiązanie, które wydaje się działać. Załączam przykład kodu:

  // Add the events to listen for 
     dataGridView1.CellValueChanged += 
      new DataGridViewCellEventHandler(dataGridView1_CellValueChanged); 
     dataGridView1.CurrentCellDirtyStateChanged += 
      new EventHandler(dataGridView1_CurrentCellDirtyStateChanged); 

    // This event handler manually raises the CellValueChanged event 
    // by calling the CommitEdit method. 
    void dataGridView1_CurrentCellDirtyStateChanged(object sender, 
     EventArgs e) 
    { 
     if (dataGridView1.IsCurrentCellDirty) 
     { 
      // This fires the cell value changed handler below 
      dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 
     } 
    } 

    private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) 
    { 
     // My combobox column is the second one so I hard coded a 1, flavor to taste 
     DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[1]; 
     if (cb.Value != null) 
     { 
       // do stuff 
       dataGridView1.Invalidate(); 
     } 
    } 
+1

To naprawdę jest lepsze niż zaakceptowane rozwiązanie. Jedyną rzeczą, którą musiałem zmienić było dodanie (np.RowIndex == -1) return; na początek funkcji dataGridView1_CellValueChanged – Kevin

+0

świetne rozwiązanie, które powinno zostać zaakceptowane. –

+2

Tak, zdecydowanie lepsze rozwiązanie, wybrane wielokrotnie uruchamia zdarzenie. –