DataBinding到具有IEnumerable <t>属性的对象 - C#</t>

时间:2014-09-04 15:45:13

标签: c# data-binding collections datagridview

我对数据绑定很新,我需要一些关于如何构建我的应用程序的一般指示。

我有类似数据库的类,如下所示:

public class Database
{
    public string FileName { get; set; }
    public List<Entry> Entries { get { return backList.ToList(); } }

    BindingList<Entry> backList = new BindingList<Entry>();
    ...
}

其中每个条目的定义如下:

public class Entry
{
    public string FileName { get; set; }
    public string Path { get; set; }
    FileInfo File { get; set; }
    public Dictionary<string, Field> Fields { get { return fields.ToDictionary(n => n.Name, f => f); } }
    HashSet<Field> fields = new HashSet<Field>();
    ...
}

我定义了这样的对象模型,因为我知道每个条目肯定包含一个FileName和一个Path。但是&#34;字段的数量和类型&#34;每个条目可能有所不同(字段在别处被定义为抽象)。假设某些条目具有字段&#34; color&#34;,而其他条目不具有。

我想在dataGridView中显示我的条目,我希望它为此目的使用dataBinding。假设我事先知道需要显示哪些列(确保FileName和Path,还有字段&#34; color&#34;和&#34; size&#34;)。

像(伪代码):

dataGridView.Columns[0] --> Entry.FileName
dataGridView.Columns[1] --> Entry.Path
dataGridView.Columns[2] --> Entry.Fields["color"]
dataGridView.Columns[3] --> Entry.Fields["size"]

但是根据我的理解,只能将dataGridView绑定到Entry,这导致:

dataGridView.Columns[0] --> Entry.FileName
dataGridView.Columns[1] --> Entry.Path
dataGridView.Columns[2] --> Entry.Fields {collection}

有什么想法吗?


编辑:

Servy的例子:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Dynamic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DataBindingTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitDataGridView();
        }

        void InitDataGridView()
        {
            DataGridView dgv = new DataGridView();
            dgv.AutoGenerateColumns = true;
            dgv.Dock = DockStyle.Fill;
            this.Controls.Add(dgv);

            Database db = new Database();

            string[] colors = new string[5]{"red","orange","yellow","green","blue"};

            for (int i = 0; i < 5; i++)
            {
                db.Add(
                    new Entry(
                        @"C:\Test\file_" + i + ".jpg",
                        new SingleField("color", colors[i]),
                        new DateField("date_created", DateTime.Now.AddDays((int)i))
                            )
                        );
            }

            var query = db.Entries.Select(entry => 
            {
                IDictionary<string, object> mappings = new ExpandoObject();
                dynamic newEntry = mappings;
                newEntry.FileName = entry.FileName;
                newEntry.Path = entry.Path;
                foreach (var field in entry.Fields)
                {
                    mappings[field.Key] = field.Value;
                }
                return newEntry;
            });

            dgv.DataSource = query.ToList();    //  Empty dataGridView
            //dgv.DataSource = db.Entries;      //  Populated dataGridView
        }
    }

    public class Database
    {
        public string FileName { get; set; }

        BindingList<Entry> entries = new BindingList<Entry>();
        public BindingList<Entry> Entries { get { return entries; } }

        public void Add(Entry newEntry)
        {
            //  ToDo: code for checking newEntry
            //
            entries.Add(newEntry);
        }
    }

    public class Entry
    {
        public string FileName { get; set; }
        public string Path { get; set; }
        FileInfo File { get; set; }

        public Dictionary<string, Field> Fields { get { return fields.ToDictionary(n => n.Name, f => f); } }
        HashSet<Field> fields = new HashSet<Field>();

        public Entry(string fileName, params Field[] fieldParams)
        {
            File = new FileInfo(fileName);
            FileName = File.Name;
            Path = File.Directory.FullName;

            foreach (Field f in fieldParams)
            {
                fields.Add(f);
            }
        }
    }

    public abstract class Field
    {
        public string Name { get; protected set; }
        public object Value { get; protected set; }
        public FieldType Type { get; protected set; }

        public Field(string name, object value)
        {
            Name = name;
            Value = value;
        }
    }

    public class SingleField : Field
    {
        public SingleField(string name, string value) : base (name, value)
        {
            Type = FieldType.Single;
        }
    }

    public class MultipleField : Field
    {
        public MultipleField(string name, params string[] values) : base (name, values)
        {
            Type = FieldType.Multiple;
        }
    }

    public class DateField : Field
    {
        public DateField(string name, DateTime date) : base (name, date)
        {
            Type = FieldType.Date;
        }
    }

    public enum FieldType
    {
        Single,
        Multiple,
        Date
    }
}

1 个答案:

答案 0 :(得分:0)

您可以使用ExpandoObject创建一个具有在运行时确定的属性的可绑定对象。您需要为每个条目创建一个。

var query = entries.Select(entry => 
{
    IDictionary<string, object> mappings = new ExpandoObject();
    dynamic newEntry = mappings;
    newEntry.FileName = entry.FileName;
    newEntry.Path = entry.Path;
    foreach(var field in fields)
        mappings[field.Key] = field.Value);
    return newEntry;
});