c# - studio - Mostrar propiedades de una propiedad de navegación en DataGridView(Propiedades de segundo nivel)
datagridview vb net 2017 (1)
Estoy tratando de mostrar varias propiedades de una entidad relacionada en un
DataGridView
en una aplicación
winforms
.
Me parece bastante normal, pero tengo problemas para encontrar ejemplos.
Es una operación de entrada de pedidos.
Datos de OrderSheet, el ID y la fecha de recogida del pedido, luego las líneas de pedido (OrderSheetItems en el modelo a continuación) en la cuadrícula.
Los elementos de línea de pedido tienen una propiedad de navegación, Producto, basada en ProductId.
Puedo usar un DataGridViewComboBoxColumn con ProductId como ValueMember y otro campo como DisplayMember.
Pero quiero incluir más datos en otras columnas, tamaño, color, material, etc.
Aquí está el código para cargar los datos.
try
{
_context.OrderSheets.Include(o => o.OrderSheetItems.Select(i => i.Product)).Load();
orderSheetBindingSource.DataSource = _context.OrderSheets.Local.ToBindingList();
}
catch (Exception ex)...
ProductId está en una columna separada solo para experimentar, que será el cuadro combinado más adelante. Entonces, ¿hay alguna manera de vincular las otras columnas a los datos en la propiedad de navegación del Producto del OrderSheetItem o tengo que manejar CellValueChanged en la identificación del producto para establecer físicamente los datos en las otras columnas? Si hay una manera de vincular las columnas, ¿sería eso a través del código en OnLoad o en algún lugar del diseñador de columnas de la vista de cuadrícula?
TIA, Mike
Puede usar cualquiera de estas opciones:
-
Utilice
DataGridViewComboBoxColumn
- Agregar propiedades correspondientes a la clase parcial de entidad secundaria
-
Dale forma a la consulta para incluir propiedades de propiedad de navegación usando
Linq
-
Utilice el evento
CellFormatting
para obtener el valor de las columnas delimitadas deCellFormatting
-
Mostrar representación de cadena de objeto anulando
ToString()
-
Use un
TypeDescriptor
personalizado para habilitar el enlace de datos aTypeDescriptor
.
Opción 1: usar DataGridViewComboBoxColumn
Uso: este enfoque sería útil especialmente en casos en los que desea mantener el control editable.
En este enfoque, puede usar
DataGridViewComboBoxColumn
para mostrar cualquier campo de propiedad de navegación.
Para mostrar múltiples subpropiedades de campo de la propiedad de navegación en la cuadrícula, use múltiples
DataGridViewComboBoxColumn
enlazados a la misma propiedad de navegación con diferentes
DisplayMember
En este enfoque, adicional a su columna
ProductId
, agregue más
DataGridViewComboBoxColumn
a la cuadrícula y luego realice estas configuraciones para todas las columnas combinadas adicionales:
-
Establezca
DataPropertyName
de ellos enProductId
-
Establezca la propiedad
DataSource
de ellos, exactamente en el mismo origen de datos que utilizó para la columna principalProductId
, por ejemploproductBindingSource
-
Establezca
ValueMember
de ellos en el mismo miembro de valor que configuró para la columna de identificación del producto, es la columna clave de su tabla de productos. (ProductId
) -
Establezca
DisplayMember
para cada uno de ellos en una columna que desee mostrar, por ejemplo, configure uno de ellos en Nombre. uno a precio, uno a tamaño, .... De esta manera puede mostrar campos de entidad relacionados. -
Establezca la propiedad
ReadOnly
de ellos entrue
. Hace que la celda sea de solo lectura. -
Si desea que las columnas sean de solo lectura Establezca la propiedad
DisplayStyle
de ellas enNothing
. Elimina el estilo desplegable.
Si desea mantener
ProductId
editable, mantenga su
DisplayStyle
en
DropDownButton
.
De esta manera, cuando cambie el valor de la columna
ProductId
usando el cuadro combinado, cuando salga de la fila y se mueva a la siguiente fila, verá otras celdas de la fila, muestra otras propiedades del producto seleccionado.
Además, dado que las otras columnas de cuadro combinado son de solo lectura y no tienen estilo de cuadro combinado, el usuario no puede cambiar su valor y actúan solo como una columna de cuadro de texto de solo lectura que muestra otras propiedades de la entidad relacionada.
Opción 2: agregar las propiedades correspondientes a la clase parcial de entidad secundaria
Uso: este enfoque sería útil cuando no necesite editar valores.
En este enfoque, puede definir propiedades en el valor de retorno de clase parcial de la entidad secundaria de la propiedad correspondiente de la entidad principal. Por ejemplo, para el nombre del producto, defina esta propiedad en la clase parcial del elemento de pedido:
public string ProductName
{
get
{
if (this.Product != null)
return this.Product.Name;
else
return string.Empty;
}
}
Luego, simplemente puede incluir productos al seleccionar artículos de pedido y vincular la columna de cuadrícula a las propiedades correspondientes del artículo de pedido.
Opción 3: dar forma a la consulta para incluir propiedades de propiedad de navegación
Uso: este enfoque sería útil cuando no necesite editar valores.
Puede configurar la consulta para incluir propiedades de propiedad de navegación. Puede usar un objeto anónimo o un modo de vista simplemente, por ejemplo:
var list = db.OrderDetails.Include("Products").Where(x=>x.OrderId==1)
.Select(x=> new OrderDetailVM() {
Id = x.Id,
ProductId = x.ProductId,
ProductName = x.Product.Name,
Price = x.Product.Price
}).ToList();
Opción 4: use el evento CellFormatting para obtener el valor de las columnas dependientes de subpropiedades
Uso: este enfoque sería útil cuando no necesite editar valores.
En este enfoque, puede usar el evento
CellFormatting
de
DataGridView
.
Simplemente puede configurar
e.Value
según el índice de columna.
Por ejemplo:
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
//I Suppose you want to show product name in column at index 3
if(e.RowIndex>=0 && e.ColumnIndex==3)
{
var orderLineItem= (OrderLineItem)(this.dataGridView1.Rows[e.RowIndex]
.DataBoundItem);
if (order!= null && orderLineItem.Product != null)
e.Value = orderLineItem.Product.Name);
}
}
Puede usar diferentes criterios para manejar diferentes columnas y mostrar diferentes subpropiedades.
También puede hacerlo más dinámico y reutilizable utilizando la reflexión.
Puede extraer el valor de la subpropiedad de la propiedad de navegación utilizando la reflexión.
Para hacerlo, debe crear una columna y establecer
DataPropertyName
en
DataPropertyName
como
Product.Name
luego en el evento
CellFormatting
, usando la reflexión, obtenga el valor de la columna.
Aquí hay un buen artículo de Antonio Bello sobre este enfoque:
Opción 5: mostrar la representación de cadena del objeto anulando
ToString()
Uso: este enfoque sería útil cuando no necesite editar valores.
Si desea mostrar solo una columna de propiedad de navegación, simplemente puede anular el método
ToString()
de la clase de propiedad de navegación y devolver el valor adecuado.
De esta manera, al mostrar una propiedad de ese tipo en la cuadrícula, verá un texto descriptivo.
Por ejemplo, en la clase parcial de
Product
, puede escribir:
public override string ToString()
{
return this.Name;
}
Opción 6: utilice un descriptor de tipo personalizado para habilitar el enlace de datos a subpropiedades
Uso: este enfoque sería útil cuando no necesite editar valores.
En este enfoque, puede crear un TypeDescriptor personalizado que le permita realizar enlaces de datos a propiedades de segundo nivel. Aquí hay un buen artículo de Linda Liu sobre este enfoque: