2009-06-12 36 views
7

¿Es posible hacer lo siguiente en un DataGridView:Windows Forms control DataGridView tiene diferentes tipos de control en la misma columna

En la misma columna que quiero cambiar el tipo de control de cada fila entre DataGridViewTextBoxColumn y DataGridViewComboBoxColumn?

(esto es porque a veces quiero mostrar una lista desplegable y otras veces solo quiero que el usuario ingrese un valor a mano alzada).

Gracias,

P. S. Estoy usando C#

+0

Muy buena pregunta. Solo es cuestión de tiempo hasta que uno enfrenta este problema cuando usa la clase DataGridView. – TheBlastOne

Respuesta

0

Puede crear su propia clase heredada de DataGridViewCell y anular los miembros virtuales adecuados (InitializeEditingControls, EditType, tal vez algunos otros). A continuación, puede crear un DataGridViewColumn con una instancia de esta clase como la plantilla de células

+0

Gracias por esto. Parece el camino correcto. Desafortunadamente soy nuevo en esto y no puedo hacer que las células aparezcan sin importar lo que haga. He modificado EditType como se sugiere. Si he heredado de say 'DataGridViewTextBoxCell' entonces puedo ver la celda, heredar de 'DataGridViewCell' y anular EditType para devolver typeof (DataGridViewTextBoxEditingControl) me da una celda en blanco, aunque puedo ver la columna. Estoy seguro de que hay algo obvio que me he perdido. –

+0

Parece que el control de modo de vista no se muestra o tiene un ancho si es cero? Puedo tabular el control, presionar F2 y escribir un valor. Cuando salgo no puedo verlo, cuando regreso al modo de edición todavía está allí. –

+0

Creo que también necesita anular PositionEditingPanel y PositionEditingControl. Pero nunca lo hice yo mismo, así que solo puedo adivinar ... Debería usar Reflector para echar un vistazo al código de DataGridViewCells estándar, probablemente le muestre lo que necesita hacer –

0

Puede crear una columna de plantilla con ambos controles, ocultar el que no desea y vincular el otro al origen de datos en el código.

+0

Las columnas de la plantilla son para ASP.NET GridView, no WinForms DataGridView ... –

+0

Ahh, mi mal. Ha pasado un tiempo desde que trabajé con WinForms. – atfergs

7

que he tenido recientemente un caso de uso similares, y terminó de escribir algo así como el código de abajo:

Escribir una célula de medida y clase Columna y anular los métodos EditType y InitializeEditingControl en la célula, a devolver diferentes controles en su caso (aquí sólo estoy enlace de datos a una lista de una clase personalizada con el campo .useCombo indicando qué control a utilizar):

// 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); 
      } 
     } 
    } 
} 

A continuación, solo agregue una columna a su DataGridView de este tipo, y el control de edición correcto debe ser usted sed

+0

+1, esto me parece bastante útil y limpio. Lo bueno de esto es que simplemente señala la clase de control de edición requerida "justo a tiempo" en el getter EditType, permite que la Grilla haga el trabajo duro, y utiliza el control de edición creado al hacer referencia a DataGridView.EditingControl. – TheBlastOne

Cuestiones relacionadas