Как связать сложный объект с DataGridView? - PullRequest
4 голосов
/ 10 мая 2011

У меня есть класс, следующий за формой:

public class Cat
{
    public string Name { get; set; }
    public string Description {get; set; }
    public List<Cheezburger> Cheezbugers { get; private set; }
};

public class Cheezburger
{
    public int PattyCount { get; set; }
    public bool CanHaz { get; set; }
};

Я хочу отображать List Кошек в DataGridView следующим образом:

---------------------------------------------------------------------------------
| Name     | Description  |  PattyCount | CanHaz   | PattyCount   | CanHaz  | etc
--------------------------------------------------------------------------------
| Felix    | Classic Cat  |  1          | true     | 3            | false   | etc
| Garfield | Fat,Lazy Cat |  2          | false    | 7            | true    | etc

И так далее ... Цель состоит в том, чтобы перечислить все Cat Cheezbuger в одном ряду. Если вы просто попытаетесь связать список Cat s, вы не получите такое поведение.

Проблема в том, что я не могу понять, как сделать сложную привязку источника между DataGridView и отдельными элементами в списке Cats.Cheezbugers. Что бы это ни стоило, я точно знаю, что каждый Cat в списке имеет одинаковое количество Cheezbuger s в своем списке.

Редактировать

Мне известно, что Комплексное связывание DataGridView задает тот же вопрос, но принятый ответ работает, только если я заранее знаю, сколько элементов в списке, а это не так. Все, что я знаю, это то, что все списки будут иметь одинаковую длину.

Ответы [ 2 ]

6 голосов
/ 10 мая 2011

Это не просто «сложная привязка», это Pivot , где вы хотите преобразовать повторяющиеся данные (список чизбургеров) в одну строку, и эта строка имеетнеопределенное количество столбцов.

Я считаю, что ваш лучший вариант здесь - написать собственный сериализатор, который позволит вам преобразовывать ваши данные в строки в формате данных XML и затем связываться с ним.Поскольку количество столбцов будет нестабильным, xml будет более щадящим, хотя я не уверен, как DataGridView справится с этим.

EDIT FOLLOWS Поскольку я не «знал», какDataGridView будет обрабатывать таблицу данных XML. Я решил написать ее и протестировать.Я работаю так, как я ожидал, и я верю, что вы захотите.

  1. Вот ваши классы кошек и чизбургеров (немного изменены)

    public class Cat
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public List<Cheezburger> Cheezbugers { get; private set; }
    
        public void AddCheezburger(Cheezburger cheezburger)
        {
            if (this.Cheezbugers == null)
                this.Cheezbugers = new List<Cheezburger>();
            this.Cheezbugers.Add(cheezburger); 
        }
    };
    
    public class Cheezburger
    {
        public int PattyCount { get; set; }
        public bool CanHaz { get; set; }
    };
    
  2. Затем вам нужно создать простую форму с двумя кнопками «привязать к объекту» (button1) и «привязать к датируемому объекту» (button2) с DataGridView, привязанным к нижней части.и закодируйте форму как:

// в редакторе следующая строка находится в блоке кода, как только я сохраню его, это не будет ..

public partial class Form1 : Form
{

    List<Cat> cats = new List<Cat>();

    public Form1()
    {
        InitializeComponent();

        cats.Add(new Cat() { Name = "Felix", Description = "Classic Cat" });
        cats.Add(new Cat() { Name = "Garfield", Description = "Fat,Lazy" });
        cats.Add(new Cat() { Name = "Tom", Description = "Wanna-Be-Mouser" });
        cats[0].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 1 });
        cats[0].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 3 });
        cats[1].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 2 });
        cats[1].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 7 });
        cats[1].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 99 });
        cats[2].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 5 });
        cats[2].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 14 });

    }

    private void button1_Click(object sender, EventArgs e)
    {
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = cats;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = serializeCats(cats);
    }

    private DataTable serializeCats(List<Cat> cats)
    {

        DataTable returnTable = new DataTable("Cats");
        returnTable.Columns.Add(new DataColumn("Name"));
        returnTable.Columns.Add(new DataColumn("Description"));
        int setID = 1;
        foreach (Cat cat in cats)
        {
            //If the row requires more columns than are present then add additional columns
            int totalColumnsRequired = (cat.Cheezbugers.Count * 2) + 2;

            while (returnTable.Columns.Count < totalColumnsRequired)
            {
                returnTable.Columns.Add(new DataColumn("Can Haz " + setID.ToString()));
                returnTable.Columns.Add(new DataColumn("Patty Count " + setID.ToString()));
                setID++;
            }
            returnTable.AcceptChanges();
            DataRow row = returnTable.NewRow();
            row[0] = cat.Name;
            row[1] = cat.Description;
            int cbi = 2; //cheezburger index
            foreach (Cheezburger cheezburger in cat.Cheezbugers)
            {
                row[cbi] = cheezburger.CanHaz;
                cbi++;
                row[cbi] = cheezburger.PattyCount;
                cbi++;
            }

            returnTable.Rows.Add(row);
        }
        return returnTable;
    }
}

Не пытайтесь заранее определять столбцы DataGridView, они будут создаваться динамически на основе источника данных.При связывании со списком кошек вы получите два столбца (имя / описание). При связывании с таблицей данных будет получено 8 столбцов, имя и описание + 6 столбцов информации о cheezburger, которые выстроены в ряд (я полагаю), как вы хотите.Cats Haz Cheezeburgers

0 голосов
/ 10 мая 2011

Если я правильно прочитал ваш вопрос, я думаю, что вы спрашиваете, как отобразить список Cheezbugers элементов для каждой кошки.

Один из концептуальных способов сделать это - связать Cheezbugers свойство Repeater с пользовательским шаблоном столбца в сетке.Другими словами, вложите репитер в столбец пользовательской сетки шаблонов и свяжите его там.Вы можете использовать шаблон элемента списка или другой формат для представления списка Cheezbugers.Он будет поддерживать любое количество элементов в списке.

РЕДАКТИРОВАТЬ: Я только что понял, что вы разрабатываете в формах Windows, а не asp.net.Существует эквивалент или разумный эквивалент повторителя в формах - DataRepeater .Может быть возможно удовлетворить ваши потребности.Идея выше та же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...