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

StackOverflow https://stackoverflow.com/questions/295141

Вопрос

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

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

class friend{
  string name;
  string address;
}

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

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

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

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

Может ли использование 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 и создавать столбец для каждого из них.

Это было полезно?

Решение

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

Основная идея заключается в том, что вы просматриваете всех возможных друзей, добавляете их имена в качестве столбца данных в 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     |      |      |     |     |
-------------------------------------------------   

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top