GridViewでTemplateField列を非表示にするにはどうすればよいですか?
私は次を試しました:
<asp:TemplateField ShowHeader="False" Visible='<%# MyBoolProperty %>' >
<ItemTemplate>
<asp:LinkButton ID="attachmentButton" runat="server" ... />
</ItemTemplate>
しかし、それは機能せず、次のエラーを出します:
データバインディング式は、DataBindingイベントを持つオブジェクトでのみサポートされます。 System.Web.UI.WebControls.TemplateFieldにはDataBindingイベントがありません。
また、プログラムで非表示にしようとしましたが、TemplateField
列には名前がないため、名前で列を取得することはできないようです。
For Each dcfColumn As DataControlField In gvGridview.Columns
If dcfColumn.HeaderText = "ColumnHeaderText" Then
dcfColumn.Visible = false
End If
Next
Visibleがfalseに設定されている行にはアクセスできず、非表示ではなくDOMから削除されていると思われる場合は、Display:Noneアプローチも使用しました。私の場合、行のキーを含む非表示の列が必要でした。私にとって、この宣言型のアプローチは、コードを使用する他のアプローチよりも少し簡潔です。
<style>
.HiddenCol{display:none;}
</style>
<%--ROW ID--%>
<asp:TemplateField HeaderText="Row ID">
<HeaderStyle CssClass="HiddenCol" />
<ItemTemplate>
<asp:Label ID="lblROW_ID" runat="server" Text='<%# Bind("ROW_ID") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Right" CssClass="HiddenCol" />
<EditItemTemplate>
<asp:TextBox ID="txtROW_ID" runat="server" Text='<%# Bind("ROW_ID") %>'></asp:TextBox>
</EditItemTemplate>
<FooterStyle CssClass="HiddenCol" />
</asp:TemplateField>
GridView1.Columns[columnIndex].Visible = false;
これを試して
.hiddencol
{
display:none;
}
.viscol
{
display:block;
}
gridViewのRowCreatedイベントに次のコードを追加します
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[0].CssClass = "hiddencol";
}
else if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].CssClass = "hiddencol";
}
}
私は何かが欠けていますか?
TemplateFieldに可視性を設定できない場合は、そのコンテンツに設定します
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Visible='<%# MyBoolProperty %>' ID="foo" runat="server" ... />
</ItemTemplate>
</asp:TemplateField>
または、コンテンツが複雑な場合は、それをdivに囲み、divに可視性を設定します
<asp:TemplateField>
<ItemTemplate>
<div runat="server" visible='<%# MyBoolProperty %>' >
<asp:LinkButton ID="attachmentButton" runat="server" ... />
</div>
</ItemTemplate>
</asp:TemplateField>
A わずか列名を使用した改善、私見:
Private Sub GridView1_Init(sender As Object, e As System.EventArgs) Handles GridView1.Init
For Each dcf As DataControlField In GridView1.Columns
Select Case dcf.HeaderText.ToUpper
Case "CBSELECT"
dcf.Visible = Me.CheckBoxVisible
dcf.HeaderText = "<small>Select</small>"
End Select
Next
End Sub
これにより、複数の列を制御できます。最初は、内部のコントロール名と一致する「技術的な」列名を使用します。これにより、ASCXページ内でコントロール列であることが明らかになります。次に、プレゼンテーションに必要な名前を交換します。本番環境で奇妙な名前をスパイした場合、何かをスキップしたことがわかります。 「ToUpper」は、ケースの問題を回避します。
最後に、これは行の作成中にイベントをキャプチャするのではなく、投稿で1回実行します。
これは別の方法で行うことができ、nullを検証できます
DataControlField dataControlField = UsersGrid.Columns.Cast<DataControlField>().SingleOrDefault(x => x.HeaderText == "Email");
if (dataControlField != null)
dataControlField.Visible = false;
protected void gvLogMessageDetail_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
if (rdlForImportOrExport.SelectedIndex == 1)
{
e.Row.Cells[3].Visible = false;
e.Row.Cells[4].Visible = false;
e.Row.Cells[5].Visible = false;
}
else
{
e.Row.Cells[3].Visible = true;
e.Row.Cells[4].Visible = true;
e.Row.Cells[5].Visible = true;
}
}
if (e.Row.RowType == DataControlRowType.DataRow) //skip header row
{
try
{
if (rdlForImportOrExport.SelectedIndex == 1)
{
e.Row.Cells[3].Visible = false;
e.Row.Cells[4].Visible = false;
e.Row.Cells[5].Visible = false;
}
else
{
e.Row.Cells[3].Visible = true;
e.Row.Cells[4].Visible = true;
e.Row.Cells[5].Visible = true;
}
}
catch
{
ClientScript.RegisterStartupScript(GetType(), "Expand", "<SCRIPT LANGUAGE='javascript'>alert('There is binding problem in child grid.');</script>");
}
}
}