簡體   English   中英

DataGridView如何獲取類中的屬性列表?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM