[英]How does DataGridView get the list of properties in a class?
當您設置List或者更好的是將BindingList作為DataGridView的源時,它會獲取屬性列表並使用它們來生成列。
如果我執行以下操作:
StatsList = new BindingList<ExpandoObject>();
// Add seed record to generate columns in DataGridView
dynamic ds = new ExpandoObject();
ds.key = "0000";
ds.Name = "Bob";
ds.Number = "2255442";
ds.key = "0001";
ds.Name = "Nathan";
ds.Number = "1217479";
StatsList.Add(ds);
dgvListView.DataSource = StatsList;
什么都沒發生。 沒有任何列或行被添加到DataGridView。 我猜這是因為缺少一個允許DataGridView獲取屬性集合的方法。
如果我運行相同的代碼,但在上面的代碼示例中使用MyCustomClass替換ExpandoObject,如下所定義,DataGridView將填充正常。
public class MyCustomClass
{
public string key { get; set; }
public string name { get; set; }
public string number { get; set; }
}
但是,由於我從可能發生變化的源讀取數據,因此我需要使用動態類。 我嘗試了很多方法,包括BindingList BindigList>都沒有將動態成員綁定到列。 我甚至嘗試使用TryGetMember和TrySetMember的覆蓋創建一個繼承DynamicObject的類。
我覺得我正在轉動輪子,忽略了一個簡單的解決方案。 也許有一些技巧使用我在這里缺少的Dictionary和Linq。
注意事項:我正在收集數據,總結並顯示數據。 一旦顯示數據,我就不需要添加或刪除數據。 我會嘗試過濾和排序它。 不過,一旦我弄明白如何展示它,我就會越過那座橋。
我的示例顯示了簡單的已知值和類型,但我的實際源數據將不太可預測,並且使用Newtonsoft JSON從JSON解析,結構如下:
[{“match_number”:1,“set_number”:1,“key”:“2017onbar_f1m1”,“score_breakdown”:{“blue”:{“totalPoints”:236,“foulCount”:1,“adjustPoints”:0, “加班”:真實},“紅色”:{“totalPoints”:236,“foulCount”:1,“adjustPoints”:0,“加班”:真}},“teammembers”:{“blue”:{“團隊“:[”member1“,”member2“,”member3“]},”red“:{”teams“:[”member4“,”member5“,”member6“]}}}]
但是,score_breakdown字段會有所不同。
嘗試將BindingList轉換為DataTable
protected void Page_Load(object sender, EventArgs e)
{
var StatsList = new BindingList<ExpandoObject>();
// Add seed record to generate columns in DataGridView
dynamic ds = new ExpandoObject();
ds.key = "0000";
ds.Name = "Bob";
ds.Number = "2255442";
dynamic ds2 = new ExpandoObject();
ds2.key = "0001";
ds2.Name = "Nathan";
ds2.Number = "1217479";
StatsList.Add(ds);
StatsList.Add(ds2);
GridView1.DataSource = ExpandoListToDataTable(StatsList);
GridView1.DataBind();
}
protected DataTable ExpandoListToDataTable(BindingList<ExpandoObject> d)
{
var dt = new DataTable();
foreach (var a in d)
{
foreach (var key in ((IDictionary<string, object>)a).Keys)
{
if (!dt.Columns.Contains(key))
{
dt.Columns.Add(key);
}
}
dt.Rows.Add(((IDictionary<string, object>)a).Values.ToArray());
}
return dt;
}
如果給定的datasource是某種類型的實例(不是Type
實例), DatagridView.DataSource
setter將使用source.GetType().GetProperties()
來檢索屬性,這些屬性將用於生成列。
問題是在你的情況下類型ExpandoObject
將返回空集合
dynamic ds = new ExpandoObject();
ds.key = "0000";
ds.Name = "Bob";
ds.Number = "2255442";
ds.GetType().GetProperties() // return empty collection
因為您在編譯時知道屬性的名稱,所以可以使用C#的新功能並創建元組
var ds = ( key: "0000", Name: "Bob", Number: "2255442" );
但是再次 - 如果您在編譯時知道屬性名稱,為什么不為它創建一個類?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.