WPF DataGrid. Lucha por la plantilla

Hola a todos!

Espero que a través de mi artículo aclare el problema de vincular la representación XML de DataGrid con su colección de código. Para esto, es mejor usar un ejemplo específico. Entonces, necesitamos colocar la lista de elementos de alguna estructura en la tabla. Digamos que los elementos se ven en el código de la siguiente manera:

class Element { public Element (string firstName, string lastName, string phoneNumber, DateTime date) { this.firstName = firstName; this.lastName = lastName; this.phoneNumber = phoneNumber; this.date = date; } public string FirstName { get { return this.firstName; } set { this.firstName = value; } } public string LastName { get { return this.lastName; } set { this.lastName = value; } } public string PhoneNumber { get { return this.phoneNumber; } set { this.phoneNumber = value; } } public DateTime Date { get { return this.date; } set { this.date = value; } } private string firstName; private string lastName; private string phoneNumber; private DateTime date; } 

En consecuencia, su lista se verá así:

 List<Element> elements = new List<Element>(); 

Ahora pasemos a DataGrid. Como todo esto es el mismo WPF, puede colocarlo en el formulario con las manos. Deje que el IDE escriba el código para ello.

 <DataGrid x:Name="dataGrid" Margin="10,103,0,15" CellEditEnding="dataGrid_CellEditEnding" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="728" AutoGenerateColumns="False"/> 

Aquí, configuro manualmente solo AutoGenerateColumns = "False", ya que en el futuro editaremos las columnas de la tabla nosotros mismos.

A continuación, debemos vincular los datos a la tabla, con cada campo del elemento correspondiente a la columna de la tabla.

 <DataGrid.Columns> <DataGridTextColumn Header="" Binding="{Binding Path=FirstName}"/> <DataGridTextColumn Header="" Binding="{Binding Path=LastName}"/> <DataGridTemplateColumn Header="" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> </DataGrid.Columns> 

Aquí se utilizan dos tipos de columnas DataGridTextColumn y DataGridTemplateColumn. Puedes leer sobre sus tipos en todas partes. Lo principal que hay que entender aquí es que con la ayuda de DataGridTemplateColumn puede configurar cualquier plantilla. Es decir, en las celdas de esta columna, será posible colocar cualquier control (botones, calendarios, etc.). Por ejemplo, en la tercera columna hay un cuadro de texto:

 <DataGridTemplateColumn Header="" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> 

IMPORTANTE: No olvide registrar el encabezado, porque la autocompletación está deshabilitada para nosotros. Y también para DataGridTemplateColumn es necesario registrar SortMemberPath, para que sepa por qué campo ordenar los datos.

Pasemos a la encuadernación. Este es el enlace de datos en sí. Lo especificamos usando Binding Path = PhoneNumber. Lo principal a considerar aquí es que este es el nombre del método de clase que devuelve el valor del campo (no phoneNumber, sino PhoneNumber, vea la descripción de la clase).
Y una cosa más. Es posible ingresar diferentes tipos de plantillas (DataTemplate) para celdas en el estado normal (CellTemplate) y en el estado de edición (CellEditingTemplate). En la cuarta columna de la celda en el estado normal es un TextBox, y en el estado de edición DatePicker:

 <DataGridTemplateColumn Header="" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 

También vale la pena señalar que cuando se trabaja con fechas, el campo Texto tiene una propiedad StringFormat que puede formatearse. Es importante que para la visualización correcta del mes "MM" sea grande.

Ahora, para vincular datos específicos a la tabla, volvamos al código en C #.
Después de llenar la matriz con elementos, debe especificarse como una fuente de datos:

 dataGrid.ItemsSource = elements; 

Por lo tanto, cualquier cambio en los elementos se mostrará en la tabla y, por el contrario, cualquier cambio realizado en la tabla dará lugar a cambios en los elementos. Pero al realizar cambios en los elementos, debe llamar al método
 dataGrid.Items.Refresh(); 
.
Y como otro buen ejemplo de un paquete de C #: XML, daré un ejemplo de verificar el llenado de las celdas de los números de teléfono con solo números. Para hacer esto, edite ligeramente el código en la tercera columna:

 <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" TextChanged="phN_TextChanged"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> 

Se puede ver que en la etiqueta TextBox asigné un controlador para el evento de cambio de texto. Ahora solo queda registrar este controlador en el código:

  private void phN_TextChanged(object sender, TextChangedEventArgs e) { int result = 0; TextBox txtx = sender as TextBox; if (txtx !=null) { if (!int.TryParse(txtx.Text, out result)) { txtx.Text = txtx.Text.Substring(0, txtx.Text.Length - 1); txtx.CaretIndex = txtx.Text.Length; } } } 

La verificación de números también se puede hacer a través de expresiones regulares.

¡Buen lanzamiento a todos!

Source: https://habr.com/ru/post/484968/


All Articles