asp.Net GridView связывает настраиваемый объект с вложенным списком

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

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

class friend{
  string name;
  string address;
}

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

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

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

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

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

Обновлять:

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

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

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

friend1 friend2
   x              peter
   x       x      adam

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


person derSteve    schedule 17.11.2008    source источник


Ответы (4)


Мне удалось решить эту проблему, используя 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;
    }
}

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

-------------------------------------------------
| 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     |      |      |     |     |
-------------------------------------------------   
person Chris Porter    schedule 13.01.2010

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

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

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

person HectorMac    schedule 17.11.2008

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

person sujata    schedule 08.01.2010

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

DataBinder.Eval (Container.DataItem, «PPP.PPP»)

person Community    schedule 28.02.2009