selecteditems personalizar examples ejemplo columns wpf datagrid

personalizar - wpf datagrid columns



¿Cómo hacer que la última columna en la red de datos de WPF ocupe todo el espacio de la izquierda, siempre? (4)

Acabo de implementar esto como un comportamiento adjunto. El problema es que cuando configura la última columna de DataGrid en *, el tamaño se ajusta para que se ajuste, pero luego todo el autoajuste de las otras celdas se desordena. Para resolver esto, el comportamiento adjunto realiza un ajuste automático manual de otras celdas (que no son las últimas).

Esto también funciona al cambiar el tamaño de las otras columnas: una vez cargadas, puede cambiar el tamaño y la última columna siempre se llenará. Tenga en cuenta que este comportamiento funciona una vez en el evento Loaded

// Behavior usage: <DataGrid DataGridExtensions.LastColumnFill="True"/> public class DataGridExtensions { public static readonly DependencyProperty LastColumnFillProperty = DependencyProperty.RegisterAttached("LastColumnFill", typeof(bool), typeof(DataGridExtensions), new PropertyMetadata(default(bool), OnLastColumnFillChanged)); public static void SetLastColumnFill(DataGrid element, bool value) { element.SetValue(LastColumnFillProperty, value); } public static bool GetLastColumnFill(DataGrid element) { return (bool)element.GetValue(LastColumnFillProperty); } private static void OnLastColumnFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var dataGrid = d as DataGrid; if (dataGrid == null) return; dataGrid.Loaded -= OnDataGridLoaded; dataGrid.Loaded += OnDataGridLoaded; } private static void OnDataGridLoaded(object sender, RoutedEventArgs e) { var dataGrid = sender as DataGrid; if (dataGrid == null) return; var lastColumn = dataGrid.Columns.LastOrDefault(); if(lastColumn != null) lastColumn.Width = new DataGridLength(1, DataGridLengthUnitType.Star); // Autofit all other columns foreach (var column in dataGrid.Columns) { if (column == lastColumn) break; double beforeWidth = column.ActualWidth; column.Width = new DataGridLength(1, DataGridLengthUnitType.SizeToCells); double sizeCellsWidth = column.ActualWidth; column.Width = new DataGridLength(1, DataGridLengthUnitType.SizeToHeader); double sizeHeaderWidth = column.ActualWidth; column.MinWidth = Math.Max(beforeWidth, Math.Max(sizeCellsWidth, sizeHeaderWidth)); } } }

Estándar WPF 4 Datagrid.

Digamos que tengo datagrid de 200 píxeles de ancho y 2 columnas. Me gustaría que las columnas ocupen todo el espacio, lo que significa que si el usuario cambia el tamaño de la primera columna a 50 píxeles, la última sería 150.

Inicialmente establecí un ancho de 100 píxeles para la primera columna, y * para la última (en XAML).

Pensé que el problema es con la eliminación de la tercera columna virtual, como se explica aquí:

http://wpf.codeplex.com/Thread/View.aspx?ThreadId=58939

pero en realidad no hay ninguna diferencia; aún así, al cambiar el tamaño de las columnas, obtengo algo de espacio adicional a la derecha: con la columna virtual, es una columna virtual (color blanco por defecto), sin ella, es un espacio vacío (gris por defecto).

PREGUNTA : cómo aplicar la restricción, que no importa cómo el usuario cambia el tamaño de las columnas,

sum(columns width)==datagrid width

?

Ediciones

Sí, utilizo WPF 4.

Trabajo

Marqué una de las respuestas como solución, pero en realidad no es una solución debido al diseño de WPF. Es simplemente lo que WPF puede hacer en el mejor de los casos, y no es muy bueno: en primer lugar, la opción CanUserResize para columna significa realmente IsResizable y esta opción cuando está activada contradice el Ancho establecido en *. Así que sin un truco realmente inteligente terminas con:

  • datagrid cuya última columna se redimensiona superficialmente, pero en realidad no lo es, y se muestra poco espacio a la derecha (es decir, la columna virtual no se puede redimensionar) - para la última columna: CanUserResize = true, Width = *

  • datagrid cuya última columna no puede ser redimensionada por el usuario y se muestra en consecuencia, inicialmente no se muestra ningún espacio a la derecha, pero se puede mostrar cuando el usuario cambia el tamaño de cualquier elemento de datagrid - para la última columna: CanUserResize = false, Width = *

Hasta ahora puedo ver dos problemas con la red de datos de WPF:

  • denominación engañosa
  • contradicción de características

Todavía soy todo oídos a cómo resolver realmente este problema.


Esté prevenido: es un truco ...

Me registré en el evento "AutoGeneratedColumns" en el método "OnLastColumnFillChanged" de la clase del y copié el método Loaded en él, y funciona. Todavía no lo he probado a fondo, así que YMMV.

Mi cambio:

private static void OnLastColumnFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var dataGrid = d as DataGrid; if (dataGrid == null) return; dataGrid.Loaded -= OnDataGridLoaded; dataGrid.Loaded += OnDataGridLoaded; dataGrid.AutoGeneratedColumns -= OnDataGrid_AutoGeneratedColumns; dataGrid.AutoGeneratedColumns += OnDataGrid_AutoGeneratedColumns; } private static void OnDataGrid_AutoGeneratedColumns(object sender, EventArgs e) { var dataGrid = sender as DataGrid; if (dataGrid == null) return; var lastColumn = dataGrid.Columns.LastOrDefault(); if (lastColumn != null) lastColumn.Width = new DataGridLength(1, DataGridLengthUnitType.Star); // Autofit all other columns foreach (var column in dataGrid.Columns) { if (column == lastColumn) break; double beforeWidth = column.ActualWidth; column.Width = new DataGridLength(1, DataGridLengthUnitType.SizeToCells); double sizeCellsWidth = column.ActualWidth; column.Width = new DataGridLength(1, DataGridLengthUnitType.SizeToHeader); double sizeHeaderWidth = column.ActualWidth; column.MinWidth = Math.Max(beforeWidth, Math.Max(sizeCellsWidth, sizeHeaderWidth)); } }

¡Ah, y no olvides agregar el espacio de nombres a la declaración XAML! :)

Arriba arriba

xmlns:ext="clr-namespace:TestProject.Extensions"

Y luego en la declaración DataGrid:

ext:DataGridExtensions.LastColumnFill="True"

Actualización : ¡Dije que el kilometraje variaría! El mío ciertamente lo hizo.

Todo ese bit de "columnas de adaptación automática" provocó que algunas de mis columnas en un DataGrid con un número variable de columnas fueran tan anchas como el encabezado de la columna. Quité esa parte y ahora parece que está funcionando en todas las DataGrids en la aplicación.

Ahora tengo:

private static void OnDataGrid_AutoGeneratedColumns(object sender, EventArgs e) { var dataGrid = sender as DataGrid; if (dataGrid == null) return; UpdateColumnWidths(dataGrid); } private static void OnDataGridLoaded(object sender, RoutedEventArgs e) { var dataGrid = sender as DataGrid; if (dataGrid == null) return; UpdateColumnWidths(dataGrid); } private static void UpdateColumnWidths(DataGrid dataGrid) { var lastColumn = dataGrid.Columns.LastOrDefault(); if (lastColumn == null) return; lastColumn.Width = new DataGridLength(1.0d, DataGridLengthUnitType.Star); }


Establezca el ancho de la cuadrícula de datos en "Auto". Está permitiendo que las columnas cambien de tamaño correctamente dentro de la misma cuadrícula, pero ha cableado el ancho a 200.

ACTUALIZACIÓN : Basado en el comentario de @micas, es posible que haya leído mal. Si ese es el caso, intente usar 100 para el ancho de la columna izquierda y 100 * para la columna derecha (observe el asterisco). Esto hará que el ancho de la columna derecha sea el 100 por defecto, pero le permitirá cambiar el tamaño para llenar la cuadrícula.


Puede establecer un ancho de columna para que comience en el código. En su constructor, agregue:

Loaded += (s, e) => dataGrid1.Columns[3].Width = new DataGridLength(1, DataGridLengthUnitType.Star);