asp.Net GridView связывает пользовательский объект с вложенным списком - PullRequest
3 голосов
/ 17 ноября 2008

У меня есть список пользовательских объектов, которые состоят из пользовательского списка.

class person{
  string name;
  int age;
  List<friend> allMyFriends;
}

class friend{
  string name;
  string address;
}

Я хочу связать список этих объектов с GridView, и Grid должен создать для каждого друга столбец и написать в нем имя. Если у некоторых людей одинаковые frined, сетка не должна создавать отдельный столбец, а использовать существующий. Если вы понимаете, о чем я. (Классы - это всего лишь несколько примеров классов, чтобы упростить мой случай)

Есть ли способ динамической настройки привязки?

Я могу изменить определения классов и т. Д., Если они должны наследоваться от некоторых интерфейсов или т. П.

Я много гуглил, но ни один пример действительно не охватывал этот случай.

Может ли использование objectSourceControl каким-то образом решить мою проблему?

Обновление:

Чтобы дать больше информации: В конце у меня есть список людей, в то время как у каждого человека в списке есть список друзей.

List<person> allPerson = new List<person>();
// fill the list
Grid.DataSource = allPerson;
Grid.DataBind()

В таблице должны быть столбцы для каждого друга, а в строках указан человек. Если у человека есть друг, в сетку необходимо поместить крест (или что-то еще).

friend1 friend2
   x              peter
   x       x      adam

В данный момент перехватывается событие RowDataBound и поскольку привязка создает только строки с именами, а не столбцами, потому что единственным свойством в моем объекте person является имя. Есть ли способ заставить привязку просмотреть свойство List в объектах person и создать столбец для каждого из них.

Ответы [ 5 ]

4 голосов
/ 13 января 2010

Я смог решить эту проблему, используя DataTable в качестве источника данных для Grid. Мне не нравится идея перехода от красивого чистого объекта к DataTable, но он обеспечивает необходимую вам динамическую привязку. Я изменил ваш объект друга, чтобы иметь несколько конструкторов. Это позволило мне очистить декларацию статического кода, но, возможно, в вашей имплементации не было необходимости.

Основная идея состоит в том, что вы пройдете всех возможных друзей, добавите их имя в качестве DataColumn в DataTable, а затем заполните данные для всех объектов-людей и их соответствующих друзей. Вероятно, это можно было бы написать для работы за одну итерацию объекта allPerson, но я предпочел две итерации, чтобы сделать код проще для чтения.

Решение написано для c # 3.5, но может быть преобразовано для более старых версий путем изменения объявления статических данных. Надеюсь, это поможет.

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // setup your person object with static data for testing
        List<person> allPerson = new List<person>()
        {
            new person() 
            { 
                name = "Dan", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("James"), new friend("John"), new friend("Matt") } 
            }, 
            new person() 
            { 
                name = "James", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan"), new friend("Matt"), new friend("Tom") } 
            }, 
            new person() 
            { 
                name = "John", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan") } 
            }, 
            new person() 
            { 
                name = "Matt", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan"), new friend("James") } 
            }, 
            new person() 
            { 
                name = "Tom", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("James") } 
            }
        };

        System.Data.DataTable dt = new System.Data.DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Age");

        foreach (person p in allPerson)
        {
            // step through each person and look at their friends
            foreach (friend f in p.allMyFriends)
            {
                // look to see if this friend has a column already
                if (!dt.Columns.Contains(f.name))
                {
                    dt.Columns.Add(f.name);
                }
            }
        }

        foreach (person p in allPerson)
        {
            // create the datarow that represents the person
            System.Data.DataRow dr = dt.NewRow();
            dr["Name"] = p.name;
            dr["Age"] = p.age;

            // find the friends and mark them
            foreach (friend f in p.allMyFriends)
            {
                dr[f.name] = "X";
            }

            dt.Rows.Add(dr);
        }

        // fill the list
        this.Grid.DataSource = dt;
        this.Grid.DataBind();

    }
}

public class person
{
    public string name;
    public int age;
    public List<friend> allMyFriends = new List<friend>();
}

public class friend
{
    public string name;
    public string address;

    public friend()
    {

    }

    public friend(string name)
    {
        this.name = name;
    }

    public friend(string name, string address)
    {
        this.name = name;
        this.address = address;
    }
}

Edit: Я забыл добавить, как это отображается.

-------------------------------------------------
| Name  | Age | James | John | Matt | Dan | Tom |
-------------------------------------------------
| Dan   | 21  | X     | X    | X    |     |     |
| James | 21  |       |      | X    | X   | X   |
| John  | 21  |       |      |      | X   |     |
| Matt  | 21  | X     |      |      | X   |     |
| Tom   | 21  | X     |      |      |     |     |
-------------------------------------------------   
1 голос
/ 17 ноября 2008

Похоже, вы пытаетесь отобразить матрицу / кросс-таблицу в GridView. Возможно, вам будет проще получить ваши данные в формате, более совместимом с этим. Вы можете написать перекрестный запрос, если используете сервер SQL.

Если вам необходимо работать с объектами в их текущем виде, создание объединенного списка друзей перед началом также может помочь, предоставив список столбцов. Затем вы можете привязать к каждому столбцу вызов функции, который может попытаться найти человека столбца в списке друзей строк.

Не красиво, но может работать ...

0 голосов
/ 08 января 2010

Вы также можете просто использовать обработчик событий RowDataBound для создания сложных привязок.

0 голосов
/ 28 февраля 2009

используйте следующее:

DataBinder.Eval (Container.DataItem, "PPP.PPP")

0 голосов
/ 17 ноября 2008

Посмотрите на мой ответ на похожий вопрос «вложенного связывания» здесь .

...