c# windows forms datagridview accordion

c# - Acordeón en Windows Forms DataGridView



accordion (1)

Esto no es realmente difícil de hacer. El mejor enfoque sería crear un UserControl dedicado y superponerlo en el lugar correcto.

Para darle espacio, simplemente cambie la Height de la fila, haciendo un seguimiento de la fila, para que pueda revertirla cuando pierda la selección.

También tendrá que decidir si se puede expandir más de una fila y qué debe hacer el usuario para expandir y restablecer la fila.

UserControl podría tener una función displayRowData(DataGridViewRow row) que podría llamar a la pantalla los campos que le interesan en sus Labels etc.

También debe tener un plan sobre cómo los Buttons interactuarán con DataGridView .

Si solo desea expandir una fila a la vez, puede crear la UC por adelantado, hacer que el DGV su Parent y ocultarlo. Más tarde, después de la interacción del usuario, como hacer clic en la fila o en una celda determinada, la movería a la fila derecha y la mostraría.

Si se puede expandir más de una fila, deberá crear varias UCs y realizar un seguimiento de ellas en una List .

Aquí hay un ejemplo mínimo para alentarlo ...:

int normalRowHeight = -1; UcRowDisplay display = new UcRowDisplay(); DataGridViewRow selectedRow = null; public Form1() { InitializeComponent(); // create one display object display = new UcRowDisplay(); display.Visible = false; display.Parent = DGV; display.button1Action = someAction; }

Después de haber llenado el DGV

// store the normal row height normalRowHeight = DGV.Rows[0].Height;

Necesita al menos estos eventos:

private void DGV_SelectionChanged(object sender, EventArgs e) { if (selectedRow != null) selectedRow.Height = normalRowHeight; if (DGV.SelectedRows.Count <= 0) { selectedRow = null; display.Hide(); return; } // assuming multiselect = false selectedRow = DGV.SelectedRows[0]; // assuming ColumnHeader show with the same height as the rows int y = (selectedRow.Index + 1) * normalRowHeight; display.Location = new Point(1, y); // filling out the whole width of the DGV. // maybe you need more, if the DGV is scrolling horizontally // or less if you show a vertical scrollbar.. display.Width = DGV.ClientSize.Width; // make room for the display object selectedRow.Height = display.Height; // tell it to display our row data display.displayRowData(selectedRow); // show the display display.Show(); } private void DGV_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e) { // enforce refresh on the display display.Refresh(); }

Aquí hay una acción de prueba activada por el botón en el objeto de visualización:

public void someAction(DataGridViewRow row) { Console.WriteLine(row.Index + " " + row.Cells[2].Value.ToString()); }

Y, por supuesto, necesita un UserControl. Aquí hay una simple, con dos etiquetas, un botón y una etiqueta adicional para cerrar la pantalla:

public partial class UcRowDisplay : UserControl { public UcRowDisplay() { InitializeComponent(); } public delegate void someActionDelegate(DataGridViewRow row); public someActionDelegate button1Action { get; set; } DataGridViewRow myRow = null; public void displayRowData(DataGridViewRow row) { myRow = row; label1.Text = row.Cells[1].Value.ToString(); label2.Text = row.Cells[0].Value.ToString(); rowDisplayBtn1.Text = row.Cells[2].Value.ToString(); } private void rowDisplayBtn1_Click(object sender, EventArgs e) { button1Action(myRow); } private void label_X_Click(object sender, EventArgs e) { myRow.Selected = false; this.Hide(); } }

Contiene tres Labels y un Button . En el diseñador se ve así:

Tenga en cuenta que para que sea un poco más fácil para mí, he modificado el DGV para

  • no tiene RowHeader; modifica la ubicación si tienes una.
  • asumió que el encabezado de la columna tiene la misma altura que una fila.
  • todas las filas (normales) para tener la misma altura.
  • configura el DGV en multiselect = false y solo lectura

Actualizar

Aquí hay un ejemplo rápido para desplazarse:

private void DGV_Scroll(object sender, ScrollEventArgs e) { DGV.PerformLayout(); var ccr = DGV.GetCellDisplayRectangle(0, selectedRow.Index, true); display.Top = ccr.Top + normalRowHeight; // ** display.Visible = (ccr.Top >= 0 && ccr.Height > 0); }

Esto (**) supone que la fila seleccionada permanecerá visible. ¡El mismo cálculo debería ocurrir en el evento SelectionChanged! Depende de usted decidir qué sucederá cuando ocurra el desplazamiento horizontal.

Tenga en cuenta que son necesarias actualizaciones similares cuando se agregan o eliminan filas antes de la fila actual. Por lo tanto, debe moverse a una función que invoque en esos casos.

Necesito implementar algún tipo de efecto de acordeón en un Windows Form DataGridView. Cuando el usuario selecciona una fila, la fila se expande para mostrar más información y, si es posible, algunos botones u otros controles. El problema es que no tengo ni idea de cómo hacer esto. Traté de buscar en la web, pero no encontré nada que pueda guiarme en la dirección correcta para crear esto. Espero que alguien pueda decirme cómo hacer esto? (no tiene que ser una muestra de código)

Creé la maqueta a continuación para mostrar lo que quiero hacer.

Pensé en ajustar la altura de las columnas y anular el método OnPaint. Solo necesito mostrar algo de texto en la primera versión. Si eso es posible, sería genial. Sé que en el futuro necesitaría colocar algunos botones u otros controles para hacer varias cosas con el elemento seleccionado. Si eso es muy complicado de lograr, omitiré esa parte por ahora. Sé que podría usar información sobre herramientas para el texto y tener columnas de botones, etc. pero en mi caso, necesito hacerlo como un acordeón.

Saludos cordiales Hans Milling ...