GridView: how to add columns based on data from a

2019-09-17 10:43发布

Adding columns to a GridView programmatically is easy.

There are examples here and here.

Here is a similar question, but it's been answered the same way - to create a datatable and bind it to the GridView.

But won't that remove the original link to the main data source?

My GridView below already has a bind to the sqldatasource below it.

            Text="Location Board" Width="100%"></asp:Label>
        <asp:GridView ID="gvLocationBoard" runat="server" AllowPaging="True" AllowSorting="True"
            AutoGenerateColumns="False" CellPadding="4" DataSourceID="sdsLocationBoard"
            ForeColor="#333333" GridLines="None">
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <Columns>
...
...
            </Columns>
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <EditRowStyle BackColor="#999999" />
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
        </asp:GridView>
        <asp:SqlDataSource ID="sdsLocationBoard" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
            SelectCommand="SELECT rce.RollCallID, v1.StudentID, v1.StudentPreferredName + ' ' + v1.StudentFamilyName AS StudentName, cs.CheckStatusName, rce.DateSubmitted, rce.StaffID, rcp.RollCallPeriod, rcp.PeriodStart, rcp.PeriodEnd FROM vwBoardingTenants AS v1 LEFT OUTER JOIN tblBoardingRollCallEntries AS rce ON rce.StudentID = v1.StudentID LEFT OUTER JOIN tblBoardingCheckStatus AS cs ON cs.CheckStatusID = rce.CheckStatusID LEFT OUTER JOIN tblBoardingRollCallPeriods AS rcp ON rcp.RollCallPeriodID = rce.RollCallPeriodID AND rcp.RowStatus = 1 AND rcp.PeriodYear = YEAR(@SelectedDate) AND dbo.fnDateOnly(@SelectedDate) BETWEEN rcp.PeriodStart AND rcp.PeriodEnd WHERE (dbo.fnDateOnly(rce.DateSubmitted) = dbo.fnDateOnly(@SelectedDate)) AND (v1.Year = YEAR(@SelectedDate))">
            <SelectParameters>
                <asp:ControlParameter ControlID="txtSelectedDate" Name="SelectedDate" Type="DateTime"/>
            </SelectParameters>
        </asp:SqlDataSource>

However, what if you're trying to add column headers to a gridview based on a data source that is totally separate (individual) to the main data source, for the overall GridView?

This is my "column" sql datasource...

<asp:SqlDataSource ID="sdsRollCallPeriods" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
            SelectCommand="SELECT RollCallPeriodID, RollCallPeriod, PeriodYear, PeriodStart, PeriodEnd, RowStatus FROM tblBoardingRollCallPeriods WHERE (RowStatus = 1) AND (PeriodYear = @PeriodYear)" 
            OnSelecting="sdsRollCallPeriods_Selecting">
            <SelectParameters>
                <asp:Parameter Name="PeriodYear" Type="Int32" />
            </SelectParameters>
        </asp:SqlDataSource>

What I want to end up with is a Gridview like this ...

User can click any of the check boxes on the right of the gridview

The checkboxes on the right and the times, as headers, are the new columns I want to add based on the sdsRollCallPeriods SqlDataSource.

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-09-17 11:18

Well it's not really a solution, but rather a work-around, and it works for me.

I've added the columns I needed and simply set them all to Visible="false".

        <asp:GridView ID="gvLocationBoard" runat="server" AllowPaging="True" AllowSorting="True" ShowFooter="false" ShowHeader="true" Visible="true" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" 
            DataSourceID="sdsLocationBoard" OnDataBound="gvLocationBoard_DataBound" OnRowDataBound="gvLocationBoard_RowDataBound" PageSize="15">
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <Columns>
                <asp:TemplateField HeaderText="RollCallID" InsertVisible="False" SortExpression="RollCallID"
                    Visible="False">
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Eval("RollCallID") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="StudentID" SortExpression="StudentID" Visible="False">
                    <ItemTemplate>
                        <asp:Label ID="Label2" runat="server" Text='<%# Eval("StudentID") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Student" SortExpression="StudentName">
                    <ItemTemplate>
                        <asp:Label ID="Label3" runat="server" Text='<%# Eval("StudentName") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Status" SortExpression="CheckStatusName" ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:Label ID="Label4" runat="server" Text='<%# Eval("CheckStatusName") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="RollCallPeriod0" Visible="False">
                    <ItemTemplate>
                        <asp:CheckBox ID="cbRollCallPeriod0" runat="server" />
                        <asp:HiddenField ID="hfRollCallPeriod0" runat="server" Value='<%# Eval("RollCallPeriod") %>' />
                    </ItemTemplate>
                    <HeaderStyle Font-Size="Small" />
                    <ItemStyle HorizontalAlign="Center" />
                </asp:TemplateField>
                <asp:TemplateField HeaderText="RollCallPeriod1" Visible="False">
                    <ItemTemplate>
                        <asp:CheckBox ID="cbRollCallPeriod1" runat="server" />
                        <asp:HiddenField ID="hfRollCallPeriod1" runat="server" Value='<%# Eval("RollCallPeriod") %>' />
                    </ItemTemplate>
                    <HeaderStyle Font-Size="Small" />
                    <ItemStyle HorizontalAlign="Center" />
                </asp:TemplateField>
..
etc with the RollCallPeriod2, 3, 4 and so on, as many as required.

I then turn them on on Page_Load(), depending on the day's worth of times I require.

    DataSourceSelectArguments args = new DataSourceSelectArguments();
    DataView dv = sdsRollCallPeriods.Select(args) as DataView;
    DataTable dt = dv.ToTable() as DataTable;
    if (dt != null)
    {
        int wsCol = 4;  //start of PeriodTimes column in gvLocationBoard
        int wsPos = 0;
        foreach (DataRow dr in dt.Rows)
        {
            gvLocationBoard.Columns[wsCol + wsPos].HeaderText = dr.ItemArray[1].ToString();
            gvLocationBoard.Columns[wsCol + wsPos].Visible = !gvLocationBoard.Columns[wsCol + wsPos].HeaderText.StartsWith("RollCallPeriod");

            wsPos += 1;
        }
    }

Voila I have my rows and my dynamic columns!

查看更多
登录 后发表回答