在DataGridView中导航属性的显示属性(第二级属性) [英] Show Properties of a Navigation Property in DataGridView (Second Level Properties)

查看:332
本文介绍了在DataGridView中导航属性的显示属性(第二级属性)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个 DataGridView的相关实体中的问题的WinForms 应用程序。看来pretty普通的给我,但我无法找到例子。这是一个订单输入操作。 OrderSheet数据,ID和该订单的拾取日期,那么在网格中的行项目(OrderSheetItems在下面的模型)。订单了LineItem具有导航属性,产品的基础上,产品编号。我可以用一个DataGridViewComboBoxColumn与作为产品编号和ValueMember另一个字段作为的DisplayMember。但我想在其他列更多的数据,尺寸,颜色,材质等。

I'm trying to display several properties from a related entity on a DataGridView in a winforms app. It seems pretty ordinary to me but I'm having trouble finding examples. It's an order entry operation. OrderSheet data, the ID and the pickup date for the order, then the line items (OrderSheetItems in the model below) in the grid. The order lineitems have a navigation property, Product, based on the ProductId. I can use a DataGridViewComboBoxColumn with ProductId as ValueMember and another field as DisplayMember. But I want to include more data in other columns, size, color, material, etc.

OrderSheet并与相关产品OrderSheetItems

订单输入

这里的code加载数据。

Here's the code for loading the data

try
{
    _context.OrderSheets.Include(o => o.OrderSheetItems.Select(i => i.Product)).Load();
    orderSheetBindingSource.DataSource = _context.OrderSheets.Local.ToBindingList();
}
catch (Exception ex)...

ProductID等于在一个单独的列只是为了试验,这将是组合框后。
那么,有没有绑定其他列的数据在OrderSheetItem的产品导航属性还是我来处理CellValueChanged产品ID物理设置在其他列的数据吗?如果有绑定列的方式,然后会是这样经由的OnLoad或网格视图列设计师?

The ProductId is in a separate column just for experimenting, that will be the combobox later. So is there a way to bind the other columns to the data in Product navigation property of the OrderSheetItem or do I have to handle CellValueChanged on the product id to physically set the data in the other columns? If there's a way to bind the columns then would that be via code in OnLoad or somewhere in the grid view columns designer?

TIA,迈克

推荐答案

选项1 - 使用DataGridViewComboBoxColumn绑定到同一属性不同的DisplayMember

在这种方法中,附加到你的产品编号列,增加更多的 DataGridViewComboBoxColumn 来的网格,然后执行这些设置所有额外的连击列:

In this approach, additional to your ProductId column, add more DataGridViewComboBoxColumn to the grid and then perform these settings for all additional combo columns:


  • 设置 DataPropertyName 它们来产品编号

  • 设置它们的数据源财产,正是您用于主产品编号列中,同一数据源例如 productBindingSource

  • 设置 ValueMember 他们对你的产品ID栏设置相同的值成员,这是你的产品表的键列。(产品编号

  • 设置的DisplayMember 为他们每个人,你要显示的列,例如,将其中一个设置为名称。一到价格,一个尺寸,...。这样你就可以显示相关的实体领域。

  • 他们中的
  • 设置只读属性真正。它使细胞只读。

  • 如果你想设置只读其中的DisplayStyle 属性没有列。它消除了下拉式的。

  • Set DataPropertyName of them to ProductId
  • Set the DataSource property of them, to exactly the same data source you used for main ProductId column, for example productBindingSource
  • Set ValueMember of them to the same value member you set for product id column, it's the key column of your product table.(ProductId)
  • Set DisplayMember for each of them to a column that you want to show, for example, set one of them to Name. one to Price, one to Size, ... . This way you can show related entity fields.
  • Set ReadOnly property of them to true. It makes the cell read only.
  • If you want to make columns readonly Set DisplayStyle property of them to Nothing. It removes dropdown style.

如果你想保持产品编号编辑,保持的DisplayStyle 的它 DropDownButton 。这当您更改产品编号列使用组合框的值,当你离开该行,并移动到下一行,你会看到一排的其他细胞的方式,显示了其他属性所选的产品。此外,由于其他组合框列是只读的,没有组合框的风格,用户不能改变他们的价值,他们的行为只喜欢一个只读文本框列,显示关联实体的其他属性。

If you want to keep ProductId editable, keep the DisplayStyle of it to DropDownButton. This way when you change the value of ProductId column using combobox, when you leave the row and moved to next row, you will see other cells of row, shows other properties of the selected product. Also since the other combobox columns are read only and have no combobox style, the user can not change the value of them and they act only like a read only text box column that show other properties from related entity.

选项2 - 添加相应的属性,以子实体部分类

在这种方法中,您可以定义相应的父实体财产的子实体部分类的返回值属性。例如,对于产品的名称,以便项目部分类定义此属性:

In this approach, You can define properties in child entity partial class return value of corresponding property of parent entity. For example for product name, define this property in order item partial class:

public string ProductName
{
    get
    {
        if (this.Product != null)
            return this.Product.Name;
        else 
            return string.Empty;
    }
}

然后,你可以直接选择产品的订单项目和电网列绑定到相应的订单项目的属性时。

Then you can simply include products when selecting order items and bind the grid column to corresponding properties of order item.

选项3 - 塑造查询包括导航财产的性质

您可以塑造查询到包括导航属性的特性。您可以使用匿名对象或只是一个视图模式,例如:

You can shape the query to include properties of navigation property. You can use an anonymous object or a View Mode simply, for example:

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();       

选项4 - 使用CellFormatting事件获得价值SUB房产界列

在此方法,您可以使用 DataGridView的 CellFormatting 事件。你可以简单地设置 e.Value 基于列的索引,例如,对于一列,子集的属性之一,另一列设置其他子属性。您也可以使用反射使它更具活力和重用。您可以提取使用反射导航属性的子属性的值。要做到这一点,你应该创建列,并设置 DataPropertyName 子属性,如 Product.Name 然后在 CellFormatting 事件,使用反射,得到列的值。下面是对这种做法的好文章由安东尼奥·贝洛:

In this approach you can use CellFormatting event of DataGridView. You can simply set e.Value based on column index, for example for one of columns, set one of sub properties and for another columns set other sub properties. Also you can make it more dynamic and reusable using reflection. You can extract the value of sub property of navigation property using reflection. To do so you should create column and set DataPropertyName to sub properties like Product.Name then in CellFormatting event, using reflection, get the value for column. Here is a good article by Antonio Bello about this approach:

  • DataGridView: How to Bind Nested Objects

选项5 - 使用自定义TypeDescriptor,以使数据绑定子性质

在此方法,您可以创建一个自定义TypeDescriptor,使您能够执行数据绑定到第二级属性。下面是对这种做法的好文章由林达刘:

In this approach you can create a custom TypeDescriptor that enables you to perform data binding to second-level properties. Here is a good article by Linda Liu about this approach:


  • 如何一个DataGridView列绑定到数据源的第二级属性
  • How to bind a DataGridView column to a second-level property of a data source

选项6 - 显示字符串重新对象的presentation通过覆盖的ToString()

Option 6 - Show string representation of object by overriding ToString()

如果您只想显示导航属性的单个列,你可以简单地覆盖的ToString()导航属性类的方法并返回合适的值。通过这种方式,显示出该类型网格的属性时,你会看到一个友好的文本。例如,在部分类产品,你可以这样写:

If you want to show only a single column of navigation property, you can simply override ToString() method of navigation property class and return suitable value. This way, when showing a property of that type in grid, you will see a friendly text. For example in partial class of Product, you can write:

public override string ToString()
{
    return this.Name;
}

这篇关于在DataGridView中导航属性的显示属性(第二级属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆