如何将 GridView 中的行数作为参数传递给 OnRowCommand 调用
How do I pass the number of rows in GridView as an argument to OnRowCommand call
我正在尝试仅当 GridView 中有超过 1 行时才在 GridView 上动态显示按钮和复选框。 (视图是基于搜索用户的结果,因此行数是基于搜索结果的动态)
按钮和复选框的用途是允许我合并 2 个或更多用户帐户。如果 GridView 中只有 1 行(令人困惑),则显示此按钮毫无意义,因此我使用函数设置 "Visible" 参数。但是,在此函数中使用 GridViewID.Rows.Count 不起作用。 (我认为它实际上是调用函数时显示的最大行数)。即:从 Gridview 的第二行调用给我 Row.Count=2。所以我试图传递一个隐藏的控件,但它不起作用。
这是我的代码:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:HiddenField ID="HiddenUserID" runat="server" Visible="false" Value= '<%#Eval("UserID") %>' ></asp:HiddenField>
<asp:HiddenField ID="NumberRowsGridView" runat="server" Visible="false" Value='<%#Bind("NumberRowsGridView") %>'></asp:HiddenField>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="UserName" HeaderText="User Name"/>
<asp:BoundField DataField="Email" HeaderText="Email Address"/>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="True" HeaderText="Merging Actions">
<ItemTemplate>
<asp:Button ID="Button3" runat="server" CausesValidation="false" CommandName="MergeIntoUser"
Text="Merge Into This Account" CommandArgument='<%# Container.DataItemIndex + "," + Eval("UserID")%>' Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
函数背后的代码:
protected Boolean ShowMergeUserButton(String Username, String Email, String NumRows)
{
return (Username == Email && Convert.ToInt32(NumRows) > 1);
}
我创建了一个隐藏字段并尝试将其插入到 GridView 中,但我的代码出现运行时错误:(注意,我是 ASP 的新手:)
protected System.Web.UI.WebControls.HiddenField NumberRowsGridView;
-- 在填充 GridView 的函数中
-- dt 为数据源
GridView1.DataSource = dt;
GridView1.DataBind();
NumberRowsGridView.Value = dt.Count<items>().ToString();
我得到的错误是:
System.Web.HttpException: DataBinding: 'MyASPPageName+dt' 不包含名称为 'NumberRowsGridView' 的 属性。
所以我基本上完全错了。
由于 OnRowCommand 是一个事件,您可以从事件处理程序中获取该信息。在您的代码隐藏中找到 GridView1_RowCommand 事件处理程序并将对象发送者转换为 GridView,如下所示...
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
GridView gridView = (GridView)sender;
int numOfRows = gridView.Rows.Count;
// Now you can do something with numOfRows!
}
至于您想做的其他事情,您可能想创建一个更具体到那些其他任务的新问题。但是不需要将行数传递给 GridView 的事件处理程序,因为发送者对象(触发事件的 GridView)将具有所有这些属性。希望这有帮助。
我不确定你想要完成什么,但这应该可以解决你的问题:
在您的代码中添加这样的 属性,ViewState
将在页面的整个生命周期中保持您的价值。
public string NumberRowsGridView
{
get { return ViewState["NumberRowsGridView"] == null ? null : ViewState["NumberRowsGridView"].ToString(); }
set { ViewState["NumberRowsGridView"] = value; }
}
现在像这样编辑这部分代码
NumberRowsGridView = dt.Count<items>().ToString();
GridView1.DataSource = dt;
GridView1.DataBind();
和这样的按钮标记
<asp:Button ID="Button3" runat="server" ... Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"), NumberRowsGridView) %>'/>
它应该可以正常工作
这不会回答您关于如何在标记中执行此操作的问题,但是当事情变得如此复杂时,我喜欢采用更简单的方法。您可以做的是 hide/show 绑定整个 GridView 后的按钮。
将 DataBound
事件添加到您的 GridView。
<asp:GridView ID="GridView1" runat="server"
OnRowCommand="GridView1_RowCommand"
OnDataBound="GridView1_DataBound">
那么在这个事件中,你所有的行都被绑定了。因此,如果您有不止一行,请显示按钮。如果没有,请隐藏按钮。这应该会给你一个想法。
protected void GridView1_DataBound(object sender, EventArgs e)
{
if (GridView1.Rows.Count > 1)
{
foreach (GridViewRow row in GridView1.Rows)
{
Button Button3 = (Button)row.FindControl("Button3");
Button3.Visible = true;
}
}
}
如果您必须在标记中这样做,Enrique Zavaleta 的回答应该可以帮助您。
我正在尝试仅当 GridView 中有超过 1 行时才在 GridView 上动态显示按钮和复选框。 (视图是基于搜索用户的结果,因此行数是基于搜索结果的动态)
按钮和复选框的用途是允许我合并 2 个或更多用户帐户。如果 GridView 中只有 1 行(令人困惑),则显示此按钮毫无意义,因此我使用函数设置 "Visible" 参数。但是,在此函数中使用 GridViewID.Rows.Count 不起作用。 (我认为它实际上是调用函数时显示的最大行数)。即:从 Gridview 的第二行调用给我 Row.Count=2。所以我试图传递一个隐藏的控件,但它不起作用。
这是我的代码:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:HiddenField ID="HiddenUserID" runat="server" Visible="false" Value= '<%#Eval("UserID") %>' ></asp:HiddenField>
<asp:HiddenField ID="NumberRowsGridView" runat="server" Visible="false" Value='<%#Bind("NumberRowsGridView") %>'></asp:HiddenField>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="UserName" HeaderText="User Name"/>
<asp:BoundField DataField="Email" HeaderText="Email Address"/>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="True" HeaderText="Merging Actions">
<ItemTemplate>
<asp:Button ID="Button3" runat="server" CausesValidation="false" CommandName="MergeIntoUser"
Text="Merge Into This Account" CommandArgument='<%# Container.DataItemIndex + "," + Eval("UserID")%>' Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
函数背后的代码:
protected Boolean ShowMergeUserButton(String Username, String Email, String NumRows)
{
return (Username == Email && Convert.ToInt32(NumRows) > 1);
}
我创建了一个隐藏字段并尝试将其插入到 GridView 中,但我的代码出现运行时错误:(注意,我是 ASP 的新手:)
protected System.Web.UI.WebControls.HiddenField NumberRowsGridView;
-- 在填充 GridView 的函数中 -- dt 为数据源
GridView1.DataSource = dt;
GridView1.DataBind();
NumberRowsGridView.Value = dt.Count<items>().ToString();
我得到的错误是: System.Web.HttpException: DataBinding: 'MyASPPageName+dt' 不包含名称为 'NumberRowsGridView' 的 属性。
所以我基本上完全错了。
由于 OnRowCommand 是一个事件,您可以从事件处理程序中获取该信息。在您的代码隐藏中找到 GridView1_RowCommand 事件处理程序并将对象发送者转换为 GridView,如下所示...
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
GridView gridView = (GridView)sender;
int numOfRows = gridView.Rows.Count;
// Now you can do something with numOfRows!
}
至于您想做的其他事情,您可能想创建一个更具体到那些其他任务的新问题。但是不需要将行数传递给 GridView 的事件处理程序,因为发送者对象(触发事件的 GridView)将具有所有这些属性。希望这有帮助。
我不确定你想要完成什么,但这应该可以解决你的问题:
在您的代码中添加这样的 属性,ViewState
将在页面的整个生命周期中保持您的价值。
public string NumberRowsGridView
{
get { return ViewState["NumberRowsGridView"] == null ? null : ViewState["NumberRowsGridView"].ToString(); }
set { ViewState["NumberRowsGridView"] = value; }
}
现在像这样编辑这部分代码
NumberRowsGridView = dt.Count<items>().ToString();
GridView1.DataSource = dt;
GridView1.DataBind();
和这样的按钮标记
<asp:Button ID="Button3" runat="server" ... Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"), NumberRowsGridView) %>'/>
它应该可以正常工作
这不会回答您关于如何在标记中执行此操作的问题,但是当事情变得如此复杂时,我喜欢采用更简单的方法。您可以做的是 hide/show 绑定整个 GridView 后的按钮。
将 DataBound
事件添加到您的 GridView。
<asp:GridView ID="GridView1" runat="server"
OnRowCommand="GridView1_RowCommand"
OnDataBound="GridView1_DataBound">
那么在这个事件中,你所有的行都被绑定了。因此,如果您有不止一行,请显示按钮。如果没有,请隐藏按钮。这应该会给你一个想法。
protected void GridView1_DataBound(object sender, EventArgs e)
{
if (GridView1.Rows.Count > 1)
{
foreach (GridViewRow row in GridView1.Rows)
{
Button Button3 = (Button)row.FindControl("Button3");
Button3.Visible = true;
}
}
}
如果您必须在标记中这样做,Enrique Zavaleta 的回答应该可以帮助您。