2012-06-06 8 views
10

Winforms .NET 3.5 (C#)Display en DataGridViewCell

I tiene un DataGridView (DGView) y I creado CustomColumn y CustomCell que se mostrarán en la DGView. Creé un CustomUserControl que quiero mostrar en CustomCell.

Problema: No veo el control del usuario en la columna. Creo que necesito anular el método Paint() en CustomCell. ¿Cómo puedo hacer eso?

Nota: el ejemplo de control de usuario de alojamiento de MSDN es para editar el valor de celda, donde hace que su control de usuario esté visible en el lugar donde está editando su celda. Quiero que mi control de usuario se represente como un control de winform normal. Este control de usuario muestra notificaciones para la fila ... y cada fila puede tener notificaciones diferentes. Quiero que los usuarios puedan hacer clic en notificaciones y obtener más detalles al respecto. .. pero por ahora estoy atascado en "cómo mostrar este control de usuario"

Cualquier puntero será muy apreciado.

public class CustomColumn : DataGridViewColumn { 
    public CustomColumn() : base(new CustomeCell()) { } 
    public override DataGridViewCell CellTemplate 
    { 
     get 
     { 
      return base.CellTemplate; 
     } 
     set 
     { 
      // Ensure that the cell used for the template is a CalendarCell. 
      if (value != null && 
       !value.GetType().IsAssignableFrom(typeof(CustomeCell))) 
      { 
       throw new InvalidCastException("It should be a custom Cell"); 
      } 
      base.CellTemplate = value; 
     } 
    } 
} 
public class CustomeCell : DataGridViewTextBoxCell 
{ 
    public CustomeCell() : base() { } 
    public override Type ValueType 
    { 
     get 
     { 
      return typeof(CustomUserControl); 
     } 
    } 
    public override Type FormattedValueType 
    { 
     get 
     { 
      return typeof(CustomUserControl); 
     } 
    } 
} 
+0

También debe definir una clase que deriva de control e implementa la interfaz IDataGridViewEditingControl. –

+0

@AngshumanAgarwal Como mencioné en mi pregunta - No quiero editar, solo quiero mostrar mi control de usuario para todas las filas en una columna. – karephul

+0

no entiendo exactamente ... pero ¿quieres mostrar los valores de las celdas no mostradas de un datagridview al usuario? (es decir, cuando el usuario hizo clic una vez en una celda), si es así, simplemente use la información sobre herramientas con SQLQuery o LINQ – sihirbazzz

Respuesta

4

Primera prueba: Intenté colocar un control de usuario en la cuadrícula donde lo necesitaba. Problema: al desplazar la vista de cuadrícula de datos, es necesario reorganizar todos esos controles de usuario. Resultado - Rechazado.

Segundo intento: Construí un control de usuario y lo pinté en la celda adecuada. Resultado - funciona hasta el momento.

Acabo de anular los métodos Paint y OnClick de DataGridViewCell en la clase CustomCell.

public class CustomeCell : DataGridViewCell 
{ 
    public override Type ValueType 
    { 
     get { return typeof(CustomUserControl); } 
    } 

    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 
    { 
     var ctrl = (CustomUserControl) value; 
     var img = new Bitmap(cellBounds.Width, cellBounds.Height); 
     ctrl.DrawToBitmap(img, new Rectangle(0, 0, ctrl.Width, ctrl.Height)); 
     graphics.DrawImage(img, cellBounds.Location); 
    } 

    protected override void OnClick(DataGridViewCellEventArgs e) 
    { 
     List<InfoObject> objs = DataGridView.DataSource as List<InfoObject>; 
     if (objs == null) 
      return; 
     if (e.RowIndex < 0 || e.RowIndex >= objs.Count) 
      return; 

     CustomUserControl ctrl = objs[e.RowIndex].Ctrl; 
     // Take any action - I will just change the color for now. 
     ctrl.BackColor = Color.Red; 
     ctrl.Refresh(); 
     DataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex); 
    } 
} 

El ejemplo hace que el CustomControl en el CustomCell de CustomColumn;). Cuando el usuario hace clic en la celda, CustomCellOnClick maneja el clic. Idealmente, me gustaría delegar ese clic en el control de usuario personalizado CustomControl, que debe manejar el evento como si fuera un clic sobre sí mismo (el control de usuario personalizado puede alojar internamente múltiples controles), por lo que es un poco complejo allí.

public class CustomColumn : DataGridViewColumn 
{ 
    public CustomColumn() : base(new CustomeCell()) { } 

    public override DataGridViewCell CellTemplate 
    { 
     get { return base.CellTemplate; } 
     set 
     { 
      if (value != null && !value.GetType() 
       .IsAssignableFrom(typeof (CustomeCell))) 
       throw new InvalidCastException("It should be a custom Cell"); 
      base.CellTemplate = value; 
     } 
    } 
} 
+0

Combiné esta solución con el patrón flyweight. Es increíble, funciona genial. – karephul

1

El control DataGridView solo es compatible con la visualización de un control real cuando una celda está en modo de edición. El control DataGridView no está diseñado para mostrar múltiples controles o repetir un conjunto de controles por fila. El control DataGridView dibuja una representación del control cuando la celda no se está editando. Esta representación puede ser detallada como lo desee. Por ejemplo, DataGridViewButtonCell dibuja un botón independientemente de si la celda está en edición o no.

Sin embargo, puede agregar controles a través del método DataGridView.Controls.Add(), y establecer su ubicación y tamaño para que sean alojados en las celdas, but showing controls in all cells regardless of editing make no sense.

Leer here

[Actualización - A partir de MS DataGridView equipo Prog Mons]

http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/394e04a8-d918-4fdd-be03-dfa13f6a1e66?persist=True

+1

MS no admite que algo sea diferente, pero no estoy de acuerdo con "pero mostrando controles en todas las celdas independientemente de la edición no tiene sentido." - Considere que está mirando la lista de pedidos de clientes - cada pedido puede tener notificaciones diferentes (sin inventario, dirección incompleta, orden duplicada, pedidos pendientes ... etc.) Me gustaría que mis usuarios "vean" estas notificaciones, idealmente en la columna llamada Notificaciones! ¡¡¡sin poder editarlos !! - pero podrá ver más detalles si hacen clic en uno de ellos. – karephul

+0

¡Interesante! Puede leer los comentarios del Administrador del programa _DataGridView. Actualicé la respuesta con el enlace msdn. –

+0

No estoy de acuerdo con "pero mostrar controles en todas las celdas independientemente de la edición no tiene sentido". Acabo de encontrar esta pregunta porque me gustaría poner un botón personalizado en una celda para hacer algo de acción en la fila seleccionada. Si eso no tiene sentido para usted, ¿por qué hay un DataGridViewButtonCell? – tapatio