LinkBut​​ton没有触发GridView_RowCommand

时间:2012-12-05 09:29:28

标签: c# asp.net gridview rowcommand

我在GridView中有一个LinkBut​​ton,它传递一个CommandArgument并尝试触发RowCommand

GridView声明:

<asp:GridView PageIndex="0" OnRowCommand="GridView1_RowCommand" PageSize="10" AllowPaging="true" OnPageIndexChanging="GridView1_PageIndexChanging"
ID="GridView1" runat="server" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None"
BorderWidth="1px" CellPadding="4" ForeColor="Black" GridLines="Horizontal" Width="700px"
AutoGenerateColumns="False" OnPageIndexChanged="GridView1_PageIndexChanged">

GridView中的LinkBut​​ton:

<asp:TemplateField>
    <ItemTemplate>
        <asp:LinkButton ID="LinkButton1" OnClientClick="return confirm('Are you sure you want to delete this checklist?');" runat="server" CausesValidation="false" CommandName="DeleteChecklist" CommandArgument='<%# Eval("refID") %>' Text="Delete"></asp:LinkButton>
    </ItemTemplate>
    <ItemStyle ForeColor="Black" />
    <ControlStyle BorderStyle="None" ForeColor="Black" />
</asp:TemplateField>

代码背后:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "DeleteChecklist")
    {
        string refID = e.CommandArgument.ToString();
        DAL.DeleteChecklist(refID);
     }
}

我在RowCommand放了一个断点,但它根本没有被解雇,任何想法为什么?

3 个答案:

答案 0 :(得分:3)

我假设你在回发上数据绑定GridView。因此,请始终将其嵌入if(!IsPostBack)支票:

protected void Page_Load(Object sender, EventArgs e)
{
    if(!IsPostBack)
    {
         GridView1.DataSource = getSource();
         GridView1.DataBind();
    }
}

否则将不会触发事件,并且将覆盖已编辑的值。

另一个可能的原因:您是否已停用ViewState

答案 1 :(得分:0)

EDIT2:好吧它好了。您可以将其与AllowCustomPaging="true"配合使用,但属性VirtualItemCount必须大于网格视图的PageSize值。看看这个:

<asp:GridView runat="server" ID="gvPresupuestos" AutoGenerateColumns="False" 
    OnRowCommand="gvPresupuestos_RowCommand" 
    OnPageIndexChanging="gvPresupuestos_PageIndexChanging" 
    OnPreRender="gvPresupuestos_PreRender" ItemType="Core.NominaEntities.TipoPresupuesto" 
    AllowPaging="true" PageSize="1" AllowCustomPaging="true"
    UseAccessibleHeader="true" GridLines="None" CssClass="table table-hover" 
    ShowHeaderWhenEmpty="True">
    <Columns>
        <asp:BoundField HeaderText="Nombre del presupuesto" DataField="Nombre" />
        <asp:TemplateField HeaderText="Opciones">
            <ItemTemplate>
                <a href='<%# "Detalle?p=" + Item.IdTipoPresupuesto.ToString() %>' 
                    target="_self"><%# Item.Editable ? "Editar" : "Ver" %></a>
                <asp:LinkButton runat="server" 
                    CommandArgument='<%# Item.IdTipoPresupuesto.ToString() %>' 
                    CommandName="Deshabilitar" 
                    Text="Deshabilitar" Visible='<%# !Item.Editable ? true : false %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

FillView()方法:

private void FillView(int desiredPage)
{
    var cliente = ClientFactory.CreateAuthServiceClient();
    using (cliente as IDisposable)
    {
        // this list only has 1 item.
        List<TipoPresupuesto> resultado = cliente.ObtenerTiposDePresupuesto();
        gvPresupuestos.DataSource = resultado;
        // For testing pursposes, force the virtual item count to 1000.
        gvPresupuestos.VirtualItemCount = 1000;
        gvPresupuestos.DataBind();
    }
}

因此,除非虚拟物品数量大于gvPresupuestos_RowCommand属性,否则LinkBut​​ton不会触发VirtualItemCount事件。

我希望这会有所帮助。

EDIT1:我找到了。您可以通过将"AllowCustomPaging"的值更改为 false 来使其有效。我不知道为什么,但希望这会有所帮助。

ORIGINAL'ANSWER':

我有同样的问题。你可以在这里看到我的代码:

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div class="jumbotron jumbotron-small">
    <h2>Presupuestos</h2>
</div>

<asp:GridView runat="server" ID="gvPresupuestos" 
AutoGenerateColumns="False" AllowPaging="true" AllowCustomPaging="true" PageSize="20"
OnRowCommand="gvPresupuestos_RowCommand" 
OnPageIndexChanging="gvPresupuestos_PageIndexChanging" 
DataKeyNames="IdTipoPresupuesto" OnPreRender="gvPresupuestos_PreRender"
ItemType="Core.NominaEntities.TipoPresupuesto"  ShowHeaderWhenEmpty="True" 
UseAccessibleHeader="true" GridLines="None" CssClass="table table-hover">
<Columns>
    <asp:BoundField HeaderText="Nombre del presupuesto" DataField="Nombre"/>
    <asp:TemplateField HeaderText="Opciones">
        <ItemTemplate>
        <asp:LinkButton runat="server" Text="Deshabilitar" 
            Font-Underline="true" CommandName="Deshabilitar" 
            Visible='<%# Item.Editable ? true : false %>'
            CommandArgument='<%# Item.IdTipoPresupuesto %>' />
        <a href='<%# "Detalle?p=" + Item.IdTipoPresupuesto.ToString() %>' 
            target="_self"><%# Item.Editable ? "Editar" : "Ver" %></a>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:ButtonField ButtonType="Link" CommandName="Deshabilitar" 
    Text="Deshabilitar (this fires event)" />
</Columns>
</asp:GridView>

<table class="large-table">
    <tr>
        <td class="text-right">
            <a runat="server" class="btn btn-primary" href="Detalle">Nuevo presupuesto</a>
        </td>
    </tr>
</table>
</asp:Content> 

背后的代码

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        InitializeControls();
        SetPermissions();
        FillView(1);
    }
}

protected void gvPresupuestos_PreRender(object sender, EventArgs e)
{
    // Habilita bootstrap
    gvPresupuestos.HeaderRow.TableSection = TableRowSection.TableHeader;
}

protected void gvPresupuestos_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // This is never fired by the LinkButton in the ItemTemplate
    // But the ButtonField actually fires it.
    if (e.CommandName.Equals("Deshabilitar"))
    {
        // This is how I've been doing it in the whole project but thanks to this 
        // shit I can't use the CommandArgument of the LinkButton in the ItemTemplate
        // Guid idPresupuesto = new Guid(e.CommandArgument.ToString());

        // I don't know what I'm supposed to do now. 
        // ¿Why this only happens in this page?, ¿WTF?
        Guid idPresupuesto = gvPresupuestos.GetTheIdFromDataKeysWithFuckingMagic();
        var cliente = ClientFactory.CreateServiceClient();
        using (cliente as IDisposable)
        {
            cliente.DeshabilitarPresupuesto(idPresupuesto);
        }
    }
    FillView(1);
}

protected void gvPresupuestos_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gvPresupuestos.PageIndex = e.NewPageIndex;
    FillView(e.NewPageIndex + 1);
}

#region helper methods
private void InitializeControls()
{
    // Not required yet
}

private void FillView(int desiredPage)
{
    var cliente = ClientFactory.CreateAuthServiceClient();
    using (cliente as IDisposable)
    {
        var resultado = cliente.ObtenerTiposDePresupuesto();
        gvPresupuestos.DataSource = resultado;
        gvPresupuestos.DataBind();
    }
}

private void SetPermissions()
{
    // not required yet
}
#endregion

我尝试在gridview中启用和禁用viewstate,但没有得到不同的结果。

以下是断点发生的情况:

  1. 您首次输入网址并加载页面。
  2. 然后你可以访问块中的代码if(!IsPostBack)。
  3. 现在您可以单击ItemTemplate中的LinkBut​​ton和ButtonField(Look screenshot
    • 如果单击ItemTemplate中的LinkBut​​ton,则不会触发gvPresupuestos_RowCommand。当然,它会进行回发。但gvPresupuestos_RowCommand 只是不会被解雇。我的代码不会处理那种奇怪的回发,而且页面会执行常规回发所做的事情。在它之后,你最终得到一个空的gridview,因为在这个回发的流程中,永远不会调用FillView()。(Look screenshot
    • 如果单击ButtonField,则会触发事件gvPresupuestos_RowCommand,一切正常。但我需要点击行的IdPresupuesto,我现在不知道如何获得它。
  4. 这很奇怪。我已经在系统的所有信息页面中实现了这个模型(有像这样的15个模块),直到现在才出现问题。

答案 2 :(得分:0)

我在ListView中的LinkBut​​ton遇到了同样的问题。 结果我应该在ListView中使用OnItemCommand,而不是OnRowCommand。

更改此问题解决了这个问题。

此外,您必须在LinkBut​​ton上设置CommandName(但不能使用OnCommand)。