2008-09-23 83 views
17

我該如何去約束下面的對象Car到一個GridView?是否可以將複雜類型屬性綁定到數據網格?

 
public class Car 
{ 
    long Id {get; set;} 
    Manufacturer Maker {get; set;} 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 

原始類型的綁定很容易,但我發現沒有辦法顯示Maker的任何東西。我想它顯示Manufacturer.Name。它甚至有可能嗎?

什麼是一種方式來做到這一點?我是否還需要在Car中存儲ManufacturerId,然後用製造商列表設置lookupEditRepository?

回答

5
public class Manufacturer 
    { 
     long Id {get; set;} 
     String Name {get; set;} 

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

重寫字符串方法。

+0

+1我認爲這是一個簡單對象的可靠解決方案 – karlipoppins 2011-04-28 17:10:37

+0

只需要一個屬性就可以了,但它不適用於您想要該對象的多個屬性。 – 2013-01-24 19:57:21

12

是的,您可以創建一個TypeDescriptionProvider來完成嵌套綁定。下面是從MSDN博客的詳細示例:

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx

+1

達到此目的的複雜程度非常高。我是否應該有另一套可以將業務對象轉換爲可能的可綁定類? – Xerx 2008-09-23 15:17:58

+0

這是一個設計決定。要麼你只是爲了綁定目的創建一堆新類,或者使用我的文章中提供的配方。就我個人而言,我討厭使用'助手'混淆我的類層次結構,所以我會選擇後者。 – 2008-09-23 15:44:44

+0

+1本文正是我所需要的...... – takrl 2012-04-16 06:38:31

2

只需使用一個列表和數據成員設置爲字符串「Maker.Name」,如果你想DataKeyField只使用汽車的ID將其設置爲「ID」。

dataGrid.DataSource = carList; 
dataGrid.DataMember = "Maker.Name"; 
dataGrid.DataKeyField = "ID"; 
dataGrid.DataBind(); 

我知道,在中繼器控制工作,至少...

7

,我在最近的應用程序走近這個問題的方法是創建自己的DataGridViewColumn和的DataGridViewCell類繼承關之一現有的如DataGridViewTextBoxColumn和DataGridViewTextBoxCell。

根據您想要的單元格類型,您可以使用其他類型,如Button,Checkbox,ComboBox等。只需查看System.Windows.Forms中可用的類型即可。

單元格將它們的值作爲對象處理,因此您可以將Car類傳遞到單元格的值中。

覆蓋SetValue和GetValue將允許您有任何額外的邏輯來處理該值。

例如:

public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell 
{ 
    protected override object GetValue(int rowIndex) 
    { 
     Car car = base.GetValue(rowIndex) as Car; 
     if (car != null) 
     { 
      return car.Maker.Name; 
     } 
     else 
     { 
      return ""; 
     } 
    } 
} 

在你需要做的主要事情是設置CellTemplate您的自定義單元格類列類。

public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn 
{ 
    public CarColumn(): base() 
    { 
     CarCell c = new CarCell(); 
     base.CellTemplate = c; 
    } 
} 

通過在DataGridView上使用這些自定義列/單元格,它允許您爲DataGridView添加很多額外的功能。

我用它們通過覆蓋GetFormattedValue將自定義格式應用於字符串值來改變顯示的格式。

我也對Paint進行了重寫,這樣我就可以根據值條件進行自定義單元格高亮顯示,根據值將單元格Style.BackColor更改爲我想要的值。

2

如果你想公開特定的嵌套屬性作爲綁定目標,那麼Ben Hoffstein的回答(http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx)非常好。引用的文章有一點鈍,但它的工作原理。

如果您只想將列綁定到複雜屬性(例如製造商)並重寫呈現邏輯,則可以執行ManiacXZ推薦的操作,或者僅子類化BoundField並提供FormatDataValue()的自定義實現。這與重寫ToString()類似。你得到一個對象引用,並返回你想要在網格中顯示的字符串。

事情是這樣的:

public class ManufacturerField : BoundField 
{ 
    protected override string FormatDataValue(object dataValue, bool encode) 
    { 
     var mfr = dataValue as Manufacturer; 

     if (mfr != null) 
     { 
      return mfr.Name + " (ID " + mfr.Id + ")"; 
     } 
     else 
     { 
      return base.FormatDataValue(dataValue, encode); 
     } 
    } 
} 

只是ManufacturerField添加到您的網格,並指定「製造商」的數據字段,你是好去。

1

我會假設你可以做到以下幾點:

public class Car 
{ 
    public long Id {get; set;} 
    public Manufacturer Maker {private get; set;} 

    public string ManufacturerName 
    { 
     get { return Maker != null ? Maker.Name : ""; } 
    } 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 
2

這裏的另一個選項我得到了工作:

<asp:TemplateColumn 
    HeaderText="Maker"> 
    <ItemTemplate> 
      <%#Eval("Maker.Name")%> 
    </ItemTemplate> 
</asp:TemplateColumn> 

可能是ASP.NET 4.0具體的,但它就像一個魅力!

22

好的傢伙......這個問題被張貼回waaay回來,但我只是發現一個相當不錯的&簡單的方法來做到這一點,通過在cell_formatting事件中使用反射來檢索嵌套屬性。

是這樣的:

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
    { 

     DataGridView grid = (DataGridView)sender; 
     DataGridViewRow row = grid.Rows[e.RowIndex]; 
     DataGridViewColumn col = grid.Columns[e.ColumnIndex]; 
     if (row.DataBoundItem != null && col.DataPropertyName.Contains(".")) 
     { 
      string[] props = col.DataPropertyName.Split('.'); 
      PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]); 
      object val = propInfo.GetValue(row.DataBoundItem, null); 
      for (int i = 1; i < props.Length; i++) 
      { 
       propInfo = val.GetType().GetProperty(props[i]); 
       val = propInfo.GetValue(val, null); 
      } 
      e.Value = val; 
     } 
    } 

就是這樣!您現在可以在DataPropertyName中爲您的列使用熟悉的語法「ParentProp.ChildProp.GrandChildProp」。

相關問題