3

カスタムリストで構成されるカスタムオブジェクトのリストがあります。

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 イベントをインターセプトします。私の個人オブジェクトの唯一のプロパティは名前であるため、バインディングは名前を持つ行のみを作成し、列は作成しないためです。バインディングが人物オブジェクトの List プロパティを調べて、それぞれの列を作成するように強制する方法はありますか。

4

4 に答える 4

4

グリッドのデータソースとして DataTable を使用してこれを解決できました。私はきれいなオブジェクトから DataTable に移行するという考えは好きではありませんが、必要な動的バインディングのサポートを提供します。あなたの友人オブジェクトをいくつかのコンストラクターを持つように変更しました。これにより、静的コード宣言をクリーンアップできましたが、実装には必要ない場合があります。

基本的な考え方は、考えられるすべての友達を調べて、その名前を DataTable に DataColumn として追加し、すべての人物オブジェクトとそれぞれの友達のデータを入力するというものです。これはおそらく allPerson オブジェクトの 1 回の反復で機能するように記述できますが、コードを読みやすくするために 2 回の反復を優先しました。

ソリューションは 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     |      |      |     |     |
-------------------------------------------------   
于 2010-01-13T19:25:41.530 に答える
1

GridView でマトリックス/クロス集計を表示しようとしているようです。これと互換性のある形式でデータを取得する方が簡単な場合があります。SQL サーバーを使用している場合は、クロス集計クエリを作成することを検討できます。

オブジェクトを現在の形で操作する必要がある場合は、開始する前に友達のマージされたリストを作成すると、列リストを提供することも役立ちます。次に、各列を関数呼び出しにバインドして、行のフレンド リストで列 person を見つけようとすることができます。

美しくはありませんが、機能する可能性があります...

于 2008-11-17T13:17:50.430 に答える
0

また、RowDataBound イベント ハンドラーを使用して、複雑なバインドを行うこともできます。

于 2010-01-08T01:49:17.120 に答える
-1

次を使用します。

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

于 2009-02-28T07:31:48.703 に答える