Come passare da DataGridViewTextBoxCell e DataGridViewComboBoxCell?
Domanda
Voglio avere un DataGridView che ha due colonne. La prima colonna sarà sempre di tipo DataGridViewComboBoxColumn. In base alla selezione in quella colonna, vorrei essere in grado di cambiare la cella corrispondente nella seconda colonna, o un DataGridViewComboBoxCell o un DataGridViewTextBoxCell.
sto pensando ho solo bisogno di fare la seconda colonna di tipo DataGridViewColumn, ma non capisco i meccanismi di come cambiare il tipo di cellula al volo.
Sto lavorando con VB.NET in Visual Studio 2005.
Grazie in anticipo!
Aggiornamento: Un modo per aggirare, suppongo, è quello di rendere la seconda colonna come DataGridViewComboBoxColumn, e cambiare gli attributi della cella in modo che esso sia si comporta come un elenco a discesa, o come (modificabile) a discesa senza elementi. Quest'ultimo sembra abbastanza come una casella di testo che ho potuto vivere con esso, e non comporterebbe la modifica del tipo di cella.
Soluzione
Non ho la versione VB.Net, ma spero che questo rapido C # frammento ti aiuterò o punto nella giusta direzione.
In questo esempio, impostare una semplice DataGridView con 2 colonne. Il primo è un DataGridViewComboBox popolato con due scelte:. "Testo" o "Combo"
La seconda colonna è impostato inizialmente DataGridViewTextBoxColumn dal progettista.
I gestire l'evento CurrentCellDirtyStateChanged sul DataGridView. Controllo se la cella è sporco e verificare solo la prima colonna (Il ComboBox). Devi chiamare il CommitEdit per ottenere il nuovo valore nel combo altrimenti si cercherà al precedente valore. In base alla selezione nella casella combinata Ho poi sovrascrivere il cellulare nel 2 ° colonna con una nuova cellula di quel tipo.
Si potrebbe aggiungere la tua logica (popolare i menu a discesa e di gestire il valore). Si potrebbe desiderare di memorizzare il valore e poi rimetterlo nella cella o qualsiasi altra cosa.
Ecco il codice che ho usato e ha fatto un test rapido e sporco su:
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty == false)
{
return;
}
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
if (((string)dataGridView1.CurrentCell.Value) == "Text")
{
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewTextBoxCell();
}
else if (((string)dataGridView1.CurrentCell.Value) == "Combo")
{
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewComboBoxCell();
}
}
}
Ecco una traduzione rapida VB, che ho testato e funziona.
Public Class Form1
Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If DataGridView1.IsCurrentCellDirty = False Then
Return
End If
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
If DataGridView1.CurrentCell.ColumnIndex = 0 Then
If CStr(DataGridView1.CurrentCell.Value) = "Text" Then
DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewTextBoxCell
ElseIf CStr(DataGridView1.CurrentCell.Value) = "Combo" Then
DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewComboBoxCell
End If
End If
End Sub
End Class
Si perde qualsiasi valore memorizzato in quella colonna, così si avrebbe bisogno di salvarlo prima.
Jon
Altri suggerimenti
È possibile creare il proprio modello di cellulare che ospita un controllo utente. Nel controllo utente si aggiunge una casella di testo e una casella combinata, e aggiungere un metodo / proprietà per mostrare uno e nasconderne un altro.
Questo esempio crea un pulsante di scelta cellulare, non è difficile cambiare il codice di ospitare un controllo utente.
dgvCell = new DataGridViewTextBoxCell(); // code to remove checkbox
dgvCell.Value = string.Empty;
dgv_modi_del_trans.Rows[1].Cells[0] = dgvCell;