QA@IT

ASP.NETのGridViewでヘッダを複数行にするときに、デザインで作成したヘッダの下にヘッダを追加したい・・・または、全部自作のヘッダでAllowSorting = trueを有効にしたい

9872 PV

http://qa.atmarkit.co.jp/q/2584
↑こちらの質問を見ながら、複数行ヘッダのGridViewを作っていたのですが
元々デザインされているヘッダの上に作ることはできるようなのですが、
デザイン時に作成したヘッダの下の行に追加する形で、ヘッダを複数行にすることはできないでしょうか

というのも、
ヘッダ追加の最後に
((GridView)sender).Controls[0].Controls.AddAt(-1, row);

とありますが
これだと、デザイン時に作成したヘッダの上に作られてしまいます
それで、
((GridView)sender).Controls[0].Controls.AddAt(0, row);

((GridView)sender).Controls[0].Controls.AddAt(1, row);

等としてみたのですが、0だとやはり上に作られ、1だと、存在しない行に追加はできないというエラーになります
デザイン時に作ったヘッダの下に追加する方法はないでしょうか

なぜこんな事をするかというと
1度、デザイン時のヘッダをShowHeader=falseにし、全てプログラム内でヘッダを作成し(もちろん最初に参照したページの方法そのまま使って)
AllowSorting = true;としてみたのですが、そうすると、ソートはできない状態で(つまりただの文字だけ)ヘッダが作成されてしまいます
セルに対して SortExpression を設定出来ればいいのでしょうがなかなかその方法もわからず
以下のようにしてみたのですが・・

GridViewRow row = new GridViewRow(2, 0, DataControlRowType.Header, DataControlRowState.Normal);
BoundField b = new BoundField();
TableHeaderCell hcDate = new TableHeaderCell();
hcDate.Controls.Add(new LiteralControl("日時"));
hcDate.RowSpan = 2;
hcDate.CssClass = "title";
hcDate.Width = 136;
b = (BoundField)hcDate;//エラーになる
b.SortExpression = "日時";
row.Cells.Add(hcDate);

多分、このSortExpressionを何とか設定出来れば、デザイン時のヘッダは気にしなくてもいいとは思うのですが・・・

質問としては
1.デザイン時のヘッダの後ろに、自作ヘッダを追加出来ないか
2.プログラム中で作成したヘッダにSortExpression を設定出来ないか
のどちらかでお願いします

回答

VBですが、参考になれば

#Region "GridView ヘッダー部の細工"
    '
    'GridView ヘッダー部の細工
    '
    Private Sub CustomHeader()
        'ヘッダー行を宣言
        Dim row As New GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Alternate)

        Dim Cell1 As New TableHeaderCell
        Dim Cell2 As New TableHeaderCell

        Cell1.Text = "勤務地"
        Cell1.Width = Unit.Pixel(48)
        Cell1.HorizontalAlign = HorizontalAlign.Center
        Cell1.Font.Bold = True

        Cell2.Text = "所属"
        Cell2.Width = Unit.Pixel(48)
        Cell2.HorizontalAlign = HorizontalAlign.Center
        Cell2.Font.Bold = True

        row.Cells.Add(Cell1)
        row.Cells.Add(Cell2)

        GridView1.Controls(0).Controls.AddAt(1, row)

    End Sub
#End Region
編集 履歴 (0)

ありがとうございます
どうも、ヘッダの作成時にではなく、
フッタを作ったときに
if (e.Row.RowType == DataControlRowType.Footer)
の時に、自作のヘッダを追加すればうまくいくみたいですね
if (e.Row.RowType == DataControlRowType.Header)
の時は、まだ、データ部ができていないので挿入しようとすると
エラーになってしまったようでした

if (e.Row.RowType == DataControlRowType.Header) {
    e.Row.TableSection = System.Web.UI.WebControls.TableRowSection.TableHeader;
    MakeHeader(GridView1, e);   //ヘッダの準備
} else if (e.Row.RowType == DataControlRowType.DataRow) {
    e.Row.TableSection = System.Web.UI.WebControls.TableRowSection.TableBody;
} else if (e.Row.RowType == DataControlRowType.Footer) {
    e.Row.TableSection = System.Web.UI.WebControls.TableRowSection.TableFooter;
    MakeHeader(GridView1, e);   //最後にヘッダを加工する
}
----------------------------------------------------
public static void MakeHeader(GridView gV, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header) {   //ヘッダの時の処理
    //既存のヘッダを2段にする準備
    e.Row.Cells[0].RowSpan = 2;     //
    e.Row.Cells[1].RowSpan = 2;     //

} else if (e.Row.RowType == DataControlRowType.Footer) {    //フッタの時の処理
    //行追加
    GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);

    TableHeaderCell hcMae = new TableHeaderCell();
    hcMae.Controls.Add(new LiteralControl("前"));
    hcMae.CssClass = "title";
    row.Cells.Add(hcMae);

    TableHeaderCell hcAto = new TableHeaderCell();
    hcAto.Controls.Add(new LiteralControl("後"));
    hcAto.CssClass = "title";
    row.Cells.Add(hcAto);

    row.TableSection = TableRowSection.TableHeader;
    gV.Controls[0].Controls.AddAt(1, row);
}
}

としたらうまくいきました(値と上のプログラムはセルをいくつかはしょっているので、結合がおかしくなりますが)

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。