2009-06-12 2 views
7

E 'possibile effettuare le seguenti operazioni in un DataGridView:controllo DataGridView Windows Form hanno diversi tipi di controllo nella stessa colonna

Nella stessa colonna, voglio cambiare il tipo di controllo di ogni riga tra il DataGridViewTextBoxColumn e DataGridViewComboBoxColumn?

(questo perché a volte voglio visualizzare un elenco a discesa e altre volte voglio solo che l'utente inserisca un valore a mano libera).

Grazie,

P.S. Utilizzo C#

+0

Ottima domanda. È solo una questione di tempo fino a quando uno affronta questo problema quando si utilizza la classe DataGridView. – TheBlastOne

risposta

0

È possibile creare la propria classe ereditata da DataGridViewCell e sovrascrivere i membri virtuali adeguati (InitializeEditingControls, EditType, forse alcuni altri). È quindi possibile creare un DataGridViewColumn con un'istanza di questa classe come il modello di cellulare

+0

Grazie per questo. Sembra la pista giusta. Sfortunatamente sono un fanatico di novità e non riesco a far apparire le cellule, qualunque cosa io faccia. Ho cancellato EditType come suggerito. Se eredito da say 'DataGridViewTextBoxCell' allora posso vedere la cella, ereditare da 'DataGridViewCell' e sovrascrivere EditType per restituire typeof (DataGridViewTextBoxEditingControl) mi dà una cella vuota - Posso vedere la colonna però. Sono sicuro che c'è qualcosa di ovvio che ho perso. –

+0

Sembra solo che il controllo della modalità di visualizzazione non sia visualizzato o abbia una larghezza se zero? Posso passare al controllo, premere F2 e digitare un valore. Quando esco non riesco a vederlo, quando torno alla modalità di modifica è ancora lì. –

+0

Penso che sia necessario ridefinire PositionEditingPanel e PositionEditingControl. Ma non l'ho mai fatto da solo, quindi posso solo indovinare ... Dovresti usare Reflector per dare un'occhiata al codice per DataGridViewCells standard, probabilmente ti mostrerà cosa devi fare –

0

È possibile creare una colonna modello con entrambi i controlli, nascondere quello che non si desidera e associare l'altro all'origine dati nel codice.

+0

Le colonne modello sono per ASP.NET GridView, non WinForms DataGridView ... –

+0

Ah, il mio male. È passato un po 'di tempo da quando ho lavorato con WinForms. – atfergs

7

Recentemente ho avuto un caso d'uso simile, e ha finito per scrivere qualcosa come il codice qui sotto:

Scrivi una cella personalizzato e la classe Colonna , e sovrascrivere i metodi EditType e InitializeEditingControl sulla cellula, per tornare diversi controlli a seconda dei casi (qui sto solo associazione dati a un elenco di una classe personalizzata con il campo .useCombo indicando quale controllo da utilizzare):

// Define a column that will create an appropriate type of edit control as needed. 
public class OptionalDropdownColumn : DataGridViewColumn 
{ 
    public OptionalDropdownColumn() 
     : base(new PropertyCell()) 
    { 
    } 

    public override DataGridViewCell CellTemplate 
    { 
     get 
     { 
      return base.CellTemplate; 
     } 
     set 
     { 
      // Ensure that the cell used for the template is a PropertyCell. 
      if (value != null && 
       !value.GetType().IsAssignableFrom(typeof(PropertyCell))) 
      { 
       throw new InvalidCastException("Must be a PropertyCell"); 
      } 
      base.CellTemplate = value; 
     } 
    } 
} 

// And the corresponding Cell type 
public class OptionalDropdownCell : DataGridViewTextBoxCell 
{ 

    public OptionalDropdownCell() 
     : base() 
    {   
    } 

    public override void InitializeEditingControl(int rowIndex, object 
     initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) 
    { 
     // Set the value of the editing control to the current cell value. 
     base.InitializeEditingControl(rowIndex, initialFormattedValue, 
      dataGridViewCellStyle); 

     DataItem dataItem = (DataItem) this.OwningRow.DataBoundItem; 
     if (dataItem.useCombo) 
     { 
      DataGridViewComboBoxEditingControl ctl = (DataGridViewComboBoxEditingControl)DataGridView.EditingControl; 
      ctl.DataSource = dataItem.allowedItems; 
      ctl.DropDownStyle = ComboBoxStyle.DropDownList; 
     } 
     else 
     { 
      DataGridViewTextBoxEditingControl ctl = (DataGridViewTextBoxEditingControl)DataGridView.EditingControl; 
      ctl.Text = this.Value.ToString(); 
     } 
    } 

    public override Type EditType 
    { 
     get 
     { 
      DataItem dataItem = (DataItem)this.OwningRow.DataBoundItem; 
      if (dataItem.useCombo) 
      { 
       return typeof(DataGridViewComboBoxEditingControl); 
      } 
      else 
      { 
       return typeof(DataGridViewTextBoxEditingControl); 
      } 
     } 
    } 
} 

Quindi aggiungi una colonna al tuo DataGridView di questo tipo e il controllo di modifica corretto dovrebbe essere u sed.

+0

+1, mi sembra abbastanza utile e pulito. La cosa interessante è che segnala semplicemente la classe di controllo di modifica richiesta "just in time" nel getter di EditType, fa in modo che Grid faccia il duro lavoro e utilizzi il controllo di modifica creato facendo riferimento a DataGridView.EditingControl. – TheBlastOne