【问题标题】:Organizing multiple levels of Column Headers组织多级列标题
【发布时间】:2014-08-06 07:54:14
【问题描述】:

几天来,我一直试图弄清楚如何在 GridView 中制作和移动标题,但我提出了一些问题,但没有得到答复。

我已经成功地继续前进,现在我正在以不同的方式处理事情。

这就是我想要创建的:

我现在已经创建了标题“Rota”,然后在下面创建了我的 GridView 中需要的日期,但是我有 3 个问题。

  • 我的数据与我拥有的行数重复。

  • 我需要将“实际”和“预期”移到天数下方。

  • 我需要在小时标签下方显示 1 - 23。

这是我目前所拥有的:

正如你所看到的,当我只想要标题时,一切都被重复了,实际和预期也需要在 T 到 S (我们需要保留第一个小时标签) 和最后我需要在“小时”标签下方显示小时数。

HTML(到目前为止):

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnDataBound="GridView1_DataBound">
                    <Columns>
<asp:TemplateField HeaderText="M" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblMonday" runat="server" Text="Hour">
             </asp:Label>

         </ItemTemplate>
         <FooterTemplate>
<asp:Label ID="lblTotal" runat="server"></asp:Label>
</FooterTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="T" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblTuesday" runat="server" Text="T">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="W" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblWednesday" runat="server" Text="W">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="T" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblThursday" runat="server" Text="T">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="F" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblFriday" runat="server" Text="F">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="S" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblSaturday" runat="server" Text="S">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>
          <asp:TemplateField HeaderText="S" ItemStyle-Width="30">
         <ItemTemplate>
             <asp:Label ID="lblSunday" runat="server" Text="S">
             </asp:Label>
         </ItemTemplate>
         </asp:TemplateField>


                        <asp:BoundField HeaderText="Required" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="70" />
                        <asp:BoundField HeaderText="Actual" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="70" />
                    </Columns>
                </asp:GridView>

C#(到目前为止):

            GridViewRow HeaderRow = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Insert);

        TableCell HeaderCell2 = new TableCell();
        HeaderCell2.Text = "Rota Data Schedule";
        HeaderCell2.ColumnSpan = 7;
        HeaderCell2.HorizontalAlign = HorizontalAlign.Center;
        HeaderRow.Cells.Add(HeaderCell2);


        GridView1.Controls[0].Controls.AddAt(0, HeaderRow);

更新

我已设法对 GridView 的布局进行排序,但 Gridview 仍在复制我的数据。

这是我的“假”数据,这就是为什么我认为我的视图搞砸了:

  private DataTable GridData()
    {
        DataTable griddt;
        griddt = new DataTable();
        griddt.Columns.Add("id", typeof(string));
        griddt.Columns.Add("Hour", typeof(int));

        DataRow griddr;

        griddr = griddt.NewRow();
        griddr["id"] = 1;
        griddr["Hour"] = 1;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 2;
        griddr["Hour"] = 2;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 3;
        griddr["Hour"] = 3;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 4;
        griddr["Hour"] = 4;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 5;
        griddr["Hour"] = 5;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 6;
        griddr["Hour"] = 6;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 7;
        griddr["Hour"] = 7;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 8;
        griddr["Hour"] = 8;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 9;
        griddr["Hour"] = 9;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 10;
        griddr["Hour"] = 10;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 11;
        griddr["Hour"] = 11;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 12;
        griddr["Hour"] = 12;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 13;
        griddr["Hour"] = 13;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 14;
        griddr["Hour"] = 14;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 15;
        griddr["Hour"] = 15;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 16;
        griddr["Hour"] = 16;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 17;
        griddr["Hour"] = 17;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 18;
        griddr["Hour"] = 18;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 19;
        griddr["Hour"] = 19;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 20;
        griddr["Hour"] = 20;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 21;
        griddr["Hour"] = 21;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 22;
        griddr["Hour"] = 22;
        griddt.Rows.Add(griddr);

        griddr = griddt.NewRow();
        griddr["id"] = 23;
        griddr["Hour"] = 23;
        griddt.Rows.Add(griddr);

        griddt.PrimaryKey = new DataColumn[] { griddt.Columns["id"] };

        return griddt;

【问题讨论】:

  • 对不起,我需要建立自己的理解才能提供帮助。我希望有一个更像在Wikipedia's Rota_(schedule) 描述下找到的网格。在您的情况下,我希望 Hour 不会作为名称出现,并希望 ExpectedActual每一天下出现。你能给我们一个更详细的例子(填充数据)你想展示什么吗?
  • @MikeGuthrie 感谢您回来。数据将只是数字,其中包含当天应该有多少员工以及实际有多少员工。我已经编辑了我的问题,因为我已经完成了布局,现在需要尝试阻止网格复制数据。
  • @MikeGuthrie 我在问题的顶部画了一张图片。顶部的 Days 将单击可点击,并将更改红色框中的数据。时间将在左边。图片应该在我的问题顶部进行解释。
  • 填充列表的可点击天数是我缺少的部分。现在对我有意义。是否有一些要求迫使您将日子作为网格本身的一部分?似乎这作为它自己的元素会简单得多。
  • @MikeGuthrie 我只需要它看起来像上面那样,如何实现它并不重要,我只是卡在所有数据重复的那一刻。你有什么建议?它需要是一个 GridView,因为当点击一天时,它会将数据绑定到 Grid 中。

标签: c# html asp.net gridview


【解决方案1】:

看看我为您所追求的布局创建的这个示例解决方案:

Aspx 标记:

<div style="width:420px; text-align:center; border:1px solid black;">
    Rota Data Schedule
    <br />
    <asp:Repeater runat="server" ID="rpDaysOfWeek">
        <ItemTemplate><asp:LinkButton runat="server" ID="lnkDay" CommandArgument='<%# Bind("DayID") %>' OnCommand="DaySelect_Command"
                Font-Bold='<%# Bind("IsSelected") %>' Text='<%# Bind("DayAbbr") %>' Width="58" BorderStyle="Solid" BorderWidth="1"
                style="margin:0 0 0 0;" BorderColor="Black" ForeColor="Black" /></ItemTemplate>
    </asp:Repeater>
    <asp:GridView runat="server" ID="gvHoursAttendance" Width="420" AutoGenerateColumns="false">
        <Columns>
            <asp:BoundField HeaderText="Hour" DataField="Hour" DataFormatString="{0:00':00'}" />
            <asp:BoundField HeaderText="Expected" DataField="ExpectedCount" />
            <asp:BoundField HeaderText="Actual" DataField="ActualCount" />
        </Columns>
    </asp:GridView>
</div>

还有代码隐藏:

private DaySelect[] Days = new DaySelect[] 
    {
        new DaySelect() { DayAbbr = "M", DayID = 1, IsSelected = true },
        new DaySelect() { DayAbbr = "T", DayID = 2 },
        new DaySelect() { DayAbbr = "W", DayID = 3 },
        new DaySelect() { DayAbbr = "T", DayID = 4 },
        new DaySelect() { DayAbbr = "F", DayID = 5 },
        new DaySelect() { DayAbbr = "S", DayID = 6 },
        new DaySelect() { DayAbbr = "S", DayID = 7 },
    };

protected void Page_Load(object sender, EventArgs e)
{
    rpDaysOfWeek.DataSource = Days;

    if (!Page.IsPostBack)
    {
        rpDaysOfWeek.DataBind();
        gvHoursAttendance.DataSource = CreateWorkHours(Days.Single(d => d.IsSelected).DayID);
        gvHoursAttendance.DataBind();
    }
}

protected void DaySelect_Command(object sender, CommandEventArgs e)
{
    int dayId = Convert.ToInt32(e.CommandArgument);
    foreach (DaySelect day in Days)
    {
        day.IsSelected = day.DayID == dayId;
    }
    rpDaysOfWeek.DataBind();
    gvHoursAttendance.DataSource = CreateWorkHours(Days.Single(d => d.IsSelected).DayID);
    gvHoursAttendance.DataBind();
}

public WorkHour[] CreateWorkHours(int dayId)
{
    return new WorkHour[]
        {
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId, Hour = 0 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId, Hour = 1 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId, Hour = 2 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId, Hour = 3 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId, Hour = 4 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId, Hour = 5 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId, Hour = 6 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId, Hour = 7 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId + 1, Hour = 8 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId + 1, Hour = 9 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId + 1, Hour = 10 },
            new WorkHour() { ActualCount = dayId, ExpectedCount = dayId + 1, Hour = 11 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId + 1, Hour = 12 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId + 1, Hour = 13 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId + 1, Hour = 14 },
            new WorkHour() { ActualCount = dayId + 1, ExpectedCount = dayId + 1, Hour = 15 },
            new WorkHour() { ActualCount = dayId * 2, ExpectedCount = dayId + 1, Hour = 16 },
            new WorkHour() { ActualCount = dayId * 2, ExpectedCount = dayId + 1, Hour = 17 },
            new WorkHour() { ActualCount = dayId * 2, ExpectedCount = dayId + 1, Hour = 18 },
            new WorkHour() { ActualCount = dayId * 2, ExpectedCount = dayId + 1, Hour = 19 },
            new WorkHour() { ActualCount = dayId - 1, ExpectedCount = dayId * 2, Hour = 20 },
            new WorkHour() { ActualCount = dayId - 1, ExpectedCount = dayId * 2, Hour = 21 },
            new WorkHour() { ActualCount = dayId - 1, ExpectedCount = dayId * 2, Hour = 22 },
            new WorkHour() { ActualCount = dayId - 1, ExpectedCount = dayId * 2, Hour = 23 },
        };
}

public class DaySelect
{
    public string DayAbbr { get; set; }
    public int DayID { get; set; }
    public bool IsSelected { get; set; }
}

public class WorkHour
{
    public int Hour { get; set; }
    public int ExpectedCount { get; set; }
    public int ActualCount { get; set; }
}

关键是要避免在网格上进行如此多的自定义。星期几用作数据的参数,但不以其他方式指示网格中的任何数据列。只需将其自行移出,让网格显示您所追求的数据——按小时出勤。 (请注意,如果您仍然希望 HourExpectedActual 与日期标签完全对齐,您可以提供明确的列宽,但我建议您不要这样做,因为日期并不是真正的列,它们是标签,所以你只会引入混乱。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    相关资源
    最近更新 更多