una tamaño tabla las imagen fila contenido como columnas celdas celda cambiar alto ajustar c# wpf layout datagrid

c# - tabla - como cambiar el tamaño de un datagridview



¿Cómo cambiar el tamaño de WPF DataGrid para que se ajuste a su contenido? (5)

Acabo de salir del mismo problema en el que tenía que dar opciones en la columna de una cuadrícula de datos para que se ajustara a su ancho según el contenido del encabezado y la celda. Use el siguiente código:

private void FitToContent() { // where dg is my data grid''s name... foreach (DataGridColumn column in dg.Columns) { //if you want to size ur column as per the cell content column.Width = new DataGridLength(1.0, DataGridLengthUnitType.SizeToCells); //if you want to size ur column as per the column header column.Width = new DataGridLength(1.0, DataGridLengthUnitType.SizeToHeader); //if you want to size ur column as per both header and cell content column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto); } }

También proporcioné una opción en columnas para ajustar según la pantalla (ancho de la cuadrícula de datos). Para eso utilicé el mismo código anterior con el siguiente cambio menor:

column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Star);

PARA TODAS LAS COLUMNAS .... :) Asegúrate de mantener HorizontalScrollVisibility en Auto.

El objetivo

Me gustaría establecer ese tamaño para el DataGrid (estándar, de WPF) para que todas las celdas (texto) sean completamente visibles. Tengo una ventana con DockPanel, con DataGrid en ella, así que cuando redimensiono la ventana, todos los widgets anidados (DockPanel y DataGrid) se redimensionan en consecuencia.

Ejemplo (edit-1)

Digamos que tiene una ventana de 100 píxeles de ancho y DataGrid con una columna, cuya celda es "el zorro marrón rápido ..." (400 píxeles de ancho). Por lo tanto, el DataGrid debería redimensionarse a 400 píxeles (probablemente más, debido al relleno) y la Ventana también debería cambiar el tamaño a 400 píxeles (también más, debido al relleno).

No encontré ningún método estándar para hacerlo (AFAIK WPF proporciona una forma de recortar el contenido al ancho deseado, mi problema es exactamente opuesto), por lo que se me ocurre una solución tan fea, que no funciona demasiado bien.

La solución

  1. iterar sobre los encabezados de DataGrid (asumiendo que son solo cadenas) y calcular el ancho requerido para el texto
  2. itere sobre las filas de DataGrid por cada columna (asumiendo que son TextBlock o TextBox) y calcule el ancho máximo requerido para el texto - agregue rellenos horizontales para TextBlock / TextBox y márgenes horizontales para la celda DataGrid
  3. sume todas las diferencias entre DataGrid ActualWidth para columnas y el ancho máximo calculado en (2)
  4. aumentar el ancho de la ventana por la diferencia calculada en (3)

EL PROBLEMA

Hice varias pruebas, y en algunos casos el ancho computado es demasiado grande (esto es un problema menor), para algunos casos es demasiado pequeño. El problema comienza en su procedimiento central: calcular el ancho requerido para TextBox / TextBlock, el ancho computado siempre es 1 unidad menos de lo que debería ser (si configuro el ancho a computado a 1, siempre se recorta 1 píxel del texto).

Entonces, ¿ qué factor estoy ignorando aquí? O quizás mejor: ¿ya existe algún método para cambiar el tamaño de DataGrid para que se ajuste a su contenido?

El código

Ancho de cálculo requerido para texto (aquí para TextBlock):

public static double TextWidth(this TextBlock widget, string text) { var formattedText = new FormattedText(text, // can use arbitrary text System.Globalization.CultureInfo.CurrentCulture, widget.FlowDirection, widget.FontFamily.GetTypefaces().FirstOrDefault(), widget.FontSize, widget.Foreground); return formattedText.Width+widget.Padding.Left+widget.Padding.Right; }

Ajustando el tamaño de la ventana para que se ajuste al contenido de DataGrid (ugly_factor es una solución fea ;-) ya que no descubrí cómo solucionarlo correctamente, lo puse en 1.3 y de esta manera mi ventana "nunca" es demasiado pequeña):

public static void AdjustWidthToDataGrid(this Window window, DataGrid dataGrid, double ugly_factor) { var max_widths = dataGrid.Columns.Select(it => window.TextWidth(it.Header as string) * ugly_factor).ToArray(); foreach (var row in Enumerable.Range(0, dataGrid.Items.Count)) foreach (var col in Enumerable.Range(0, dataGrid.Columns.Count)) { var cell = dataGrid.GetCell(row, col); double width = 0; if (cell.Content is TextBlock) width = (cell.Content as TextBlock).TextWidth(); else if (cell.Content is TextBox) width = (cell.Content as TextBox).TextWidth(); if (cell.Content is FrameworkElement) { var widget = cell.Content as FrameworkElement; width = width + widget.Margin.Left + widget.Margin.Right; } max_widths[col] = Math.Max(max_widths[col], width*ugly_factor+cell.Padding.Left+cell.Padding.Right); } double width_diff = 0; foreach (var col in Enumerable.Range(0, dataGrid.Columns.Count)) width_diff += Math.Max(0,max_widths[col] - dataGrid.Columns[col].ActualWidth); if (width_diff > 0) window.Width = window.ActualWidth+ width_diff; }


En mi caso, encontré que DataGrid usa HorizontalAlignment="Stretch" VerticalAlignment="Stretch" en forma predeterminada, así que lo configuré en

<DataGrid ItemsSource="{Binding Source}" Width="Auto" Height="Auto" HorizontalAlignment="Center" VerticalAlignment="Center"/>

Entonces trabaja.


Si entendí bien tu pregunta y quieres:

  1. Un DataGrid donde las columnas son tan anchas como su contenido más amplio.
  2. El DataGrid se ajusta a su contenido.

Esto se puede lograr con el enlace de datos:

<DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="111" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="72,203,0,0" Name="dataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="{Binding Path=ActualWidth, ElementName=grid}"> <DataGrid.Columns> <DataGridTextColumn x:Name="Column1" Binding="{Binding Path=Something1}" Header="Column1" Width="Auto" /> <DataGridTextColumn x:Name="Column2" Binding="{Binding Path=Something2}" Header="Column2" Width="*" /> </DataGrid.Columns> </DataGrid>

Aquí, la primera columna es tan amplia como se necesita y la segunda es el espacio extendido que queda. Sin embargo, el ancho del DataGrid es el mismo que el ancho de Grid que lo rodea, por lo que se logra el resultado deseado.


SizeToCells es lo que funcionó para mí. Me gusta esto porque está en XAML y es conciso.

<DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}" Header="Name" Width="SizeToCells"/>


El comentario de Marko es la respuesta:

Estoy un poco perdido con su lógica de cambio de tamaño. En primer lugar, si configura SizeToContent="WidthAndHeight" la ventana, la ventana se muestra en el tamaño completo de la base de datos. Por otro lado, si muestra una ventana en un tamaño predefinido y desea cambiar el tamaño de la ventana una vez que se muestra la ventana, en ese punto, cambiar el tamaño a la base de datos deseada es muy intuitivo. Porque el cambio de tamaño cambiará de, por ejemplo, 100px a 400px, pero ¿qué ocurre si deseo cambiar el tamaño a solo 250px ... (asumiendo que usted cambia el tamaño arrastrando la esquina de la ventana)?