简体   繁体   English

使用复杂对象的嵌套 asp 中继器

[英]Nested asp repeaters using complex object

I have a complex object with nested collection of objects that need to be binded to a repeater/shown in a table.我有一个复杂的对象,其中包含需要绑定到转发器/显示在表格中的嵌套对象集合。 Object shows 14 items:对象显示 14 个项目:

在此处输入图片说明

I would like to display data as such:我想这样显示数据:

在此处输入图片说明

Objects looks like:对象看起来像:

在此处输入图片说明

I need to show "FieldName" in table/column header and "FieldValue" in the table rows.我需要在表/列标题中显示“FieldName”,在表行中显示“FieldValue”。 Notice item 3 and 5 are both "Phone Number" FieldName.注意第 3 项和第 5 项都是“电话号码”字段名称。 So I need PhoneNumber to show once (in column header) then there would be 2 rows showing 2 phonenumber FieldValues (like in the table screenshot).所以我需要 PhoneNumber 显示一次(在列标题中)然后会有 2 行显示 2 个电话号码 FieldValues(如表格截图中所示)。 So there could be multiple sets of items in the collection..eg N number of Contacts, etc. I am not sure how to set up the repeaters (or how many to use) and /or how to set up repeaters OnItemDataBound.所以集合中可能有多组项目......例如N个联系人等。我不确定如何设置转发器(或使用多少)和/或如何设置转发器OnItemDataBound。 Any ideas or pseudo code pointed in the right direction would be super helpful.任何指向正确方向的想法或伪代码都会非常有帮助。

Ok, so the question is simple this:好的,所以问题很简单:

I have a list of names, and for each name, I may have a child table of phone numbers.我有一个名字列表,对于每个名字,我可能有一个电话号码子表。 They might have no phone numbers, they might have 5 phone numbers.他们可能没有电话号码,他们可能有 5 个电话号码。

What is a good way to display this master reocrd, and then a repeating child record for each row?显示此主记录的好方法是什么,然后是每行重复的子记录?

There are LOT of ways to do this.有很多方法可以做到这一点。 I would often suggest that for the main display of rows, we use a listview, and then nest for the child rows a gridview.我经常建议,对于行的主要显示,我们使用列表视图,然后为子行嵌套网格视图。

However, as always, which road will depend on how much data, and how many rows (complex) the child data display has to be?但是,一如既往,哪条路将取决于多少数据,以及子数据显示必须是多少行(复杂)?

But, lets go with a simple grid.但是,让我们使用一个简单的网格。 As such a setup becomes more complex, then I STRONG suggest going with a listview.由于这样的设置变得更加复杂,我强烈建议使用列表视图。 The listview is better since it FAR more flexiblilty in terms of layout.列表视图更好,因为它在布局方面更加灵活。 and while the "set up" is a bit more markup, adding new columns and complex controls for each row is MUCH better.虽然“设置”是更多的标记,但为每一行添加新列和复杂控件要好得多。 In the long run the listview in fact can wind up being less overall markup.从长远来看,列表视图实际上可能会降低整体标记。

However, we only have two extra columns of "child repeating" data.但是,我们只有两列额外的“子重复”数据。

So we have in effect this:所以我们实际上是这样的:

 table people  - our list of contacts/people
 table Phones  - our child list of phone numbers for each "people".

So, lets whip up a grid with the table people.所以,让我们和桌子上的人一起制作一个网格。 I will often fire up and let the wizard create that grid.我会经常启动并让向导创建该网格。 I THEN blow out (delete) the data source in the web page, and then start using the delete keys to remove extra junk. I THEN 吹出(删除)网页中的数据源,然后开始使用删除键删除多余的垃圾。

So, we now have this markup:所以,我们现在有了这个标记:

<div style="width:30%">
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
        DataKeyNames="ID" CssClass="table">
        <Columns>
            <asp:BoundField DataField="Firstname" HeaderText="Firstname"  />
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="City" HeaderText="City"  />
        </Columns>
    </asp:GridView>
</div>

And our code to fill this grid is this:我们填充这个网格的代码是这样的:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        DataTable rst = MyRst("SELECT * from People Order by FirstName");
        GridView1.DataSource = rst;
        GridView1.DataBind();
    }

    public DataTable MyRst(string strSQL)
    {
        DataTable rstData = new DataTable();
        using (SqlCommand cmdSQL = new SqlCommand(strSQL,
            new SqlConnection(Properties.Settings.Default.TEST4)))
        {
            cmdSQL.Connection.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
        return rstData;
    }

And our output is this:我们的输出是这样的:

在此处输入图片说明

Ok, so we have this setup of course:好的,所以我们当然有这个设置:

在此处输入图片说明

now, we could have done a query join, but then again, that would repeat the main row for each child row (and then we would have to "hide" that.现在,我们可以做一个查询连接,但话又说回来,这将重复每个子行的主行(然后我们将不得不“隐藏”它。

So, lets go to the markup and add the two rows.因此,让我们转到标记并添加两行。 (PhoneType and PhoneNumber). (电话类型和电话号码)。

So we now have this:所以我们现在有这个:

<div style="width:40%">
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
        DataKeyNames="ID" CssClass="table">
        <Columns>
            <asp:BoundField DataField="Firstname" HeaderText="Firstname"  />
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="City" HeaderText="City"  />

            <asp:TemplateField HeaderText="Type">
                <ItemTemplate>
                    <asp:label ID="txtType" runat="server" Text = '<%# Eval("PhoneType") %>'></asp:label>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Phone">
                <ItemTemplate>
                    <asp:label ID="txtPhone" runat="server" Text = '<%# Eval("Phone") %>' ></asp:label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>  
    </asp:GridView>
</div>

(this is what I mean by using gridview - to drop in nice plane jane asp.net controls (a label in this case), you have to surround it with the itemtemplate - I find that a bit of pain if you have "lots" of columns. so if you need lots of custom columns then a list view is better. but we not too bad so far. (这就是我使用 gridview 的意思 - 放入漂亮的平面 jane asp.net 控件(在这种情况下是一个标签),你必须用 itemtemplate 包围它 - 如果你有“很多”,我发现有点痛苦列。所以如果你需要很多自定义列,那么列表视图会更好。但到目前为止我们还不错。

So, our code now becomes this: We simply pull the data for each child row, and shove the results of this child table into our two new columns we add.所以,我们的代码现在变成了这样:我们简单地提取每个子行的数据,并将这个子表的结果推送到我们添加的两个新列中。

this:这个:

   void LoadGrid()
    {
        DataTable rst = MyRst("SELECT * from People Order by FirstName");

        rst.Columns.Add("PhoneType", typeof(string));
        rst.Columns.Add("Phone", typeof(string));

        foreach (DataRow OneRow in rst.Rows)
        {
            // get child rows for this main row
            DataTable ChildRows = MyRst("SELECT * from Phones where People_ID = " + OneRow["ID"]);

            foreach (DataRow ChildRow in ChildRows.Rows)
            {
                if (OneRow["PhoneType"].ToString() != "")
                {
                    // start new line in this cell
                    OneRow["PhoneType"] += "<br/>";
                    OneRow["Phone"] += "<br/>";
                }
                OneRow["PhoneType"] += ChildRow["PhoneType"].ToString();
                OneRow["Phone"] += ChildRow["PhoneNumber"].ToString();
            }
        }

        GridView1.DataSource = rst;
        GridView1.DataBind();
    }

So this was a bit of extra code to loop!所以这是一些额外的循环代码! In fact, in MOST cases, if we are writing looping code, then we tend to be doing this the wrong way.事实上,在大多数情况下,如果我们正在编写循环代码,那么我们往往会以错误的方式这样做。

We now have this:我们现在有这个:

在此处输入图片说明

And it also depends on what we want to do here.这也取决于我们想在这里做什么。 Say we needed a click button for each of the child phone numbers (maybe a email also included).假设我们需要每个子电话号码的点击按钮(可能还包括电子邮件)。 So if we had to click on the child email/phone to take action, then obvious the above approach is a bit quick and dirty, but would not give us the ability to click on a particular phone number row to select.因此,如果我们必须点击子电子邮件/电话来采取行动,那么显然上述方法有点快速和肮脏,但不会让我们能够点击特定的电话号码行进行选择。

So, say if for some reason we wanted a click event, or button to select the given child row from this display?那么,假设由于某种原因我们想要一个点击事件或按钮来从这个显示中选择给定的子行?

Then I would then move over to nesting a child grid.然后我会转移到嵌套子网格。 We would not thus need a loop to fill the child data - but in fact would bind a new grid in a simular fashion to how we built the main grid.因此,我们不需要循环来填充子数据 - 但实际上将以类似方式将新网格绑定到我们构建主网格的方式。

and as noted, I would probably jump over to a list view for the main grid.如前所述,我可能会跳转到主网格的列表视图。

If you wish, I can and will post a working example of a nesting a grid view inside of list view - say with a extra button to click on the child row as a "action" we might want to take.如果你愿意,我可以并且会发布一个在列表视图中嵌套网格视图的工作示例 - 说一个额外的按钮来点击子行作为我们可能想要采取的“动作”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM