Сортировка GridView с помощью ImageButtons и Delete Command не работает

У меня есть элемент управления GridView, который имеет 5 связанных полей с включенной сортировкой и 4 поля шаблона. Одним из полей шаблона является кнопка «Удалить изображение», которая при нажатии удаляет строку. Теперь все в порядке, когда пользователи просто использовали gridview как есть, без сортировки. Но когда они сортируют его и затем нажимают удалить, аргумент команды получает неправильную информацию о строке и удаляет ее вместо того, чтобы удалить то, что они решили удалить. Это происходит только с двумя полями шаблона, которые имеют элемент управления кнопкой изображения.

<Columns>
        <asp:BoundField DataField="AccountNo" HeaderText="Account No" 
            SortExpression="AccountNo" />
        <asp:BoundField DataField="Address" HeaderText="Address" 
            SortExpression="Address" />
        <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
        <asp:BoundField DataField="Name" HeaderText="Name" 
            SortExpression="Name" />
        <asp:BoundField DataField="State" HeaderText="State" SortExpression="State" />
        <asp:BoundField DataField="Zip" HeaderText="Zip" SortExpression="Zip" />
        <asp:BoundField DataField="Utility" HeaderText="Utility" 
            SortExpression="Utility" />                
        <asp:TemplateField HeaderText="Edit">
            <ItemTemplate>
                <asp:HyperLink runat="server" ID="EditLink"  ToolTip="Edit Account" NavigateUrl='<%# GetEditURL(((BillingEntity)Container.DataItem).Id) %>' >
                    <img src="../img/edit.png" border="0"/>
                </asp:HyperLink>
            </ItemTemplate>
            <ItemStyle HorizontalAlign="Center"></ItemStyle>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Enable/Disable" >
            <ItemTemplate>
                <asp:ImageButton runat="server" ID="DisableButton" ImageUrl = "../img/delete.png" ToolTip="Disable Account" CommandName="Disable_Account" CommandArgument='<%#((BillingEntity)Container.DataItem).Id %>' OnClientClick="if (confirm('Are you sure you want to disable this account?')==false) {return false;}" Visible='<%# ShowDisableButton(((BillingEntity)Container.DataItem).Status)%>'/>
                <asp:ImageButton runat="server" ID="EnableButton" ImageUrl = "../img/add.png" ToolTip="Enable Account" CommandName="Enable_Account" CommandArgument='<%#((BillingEntity)Container.DataItem).Id %>'   Visible='<%# ShowEnableButton(((BillingEntity)Container.DataItem).Status)%>'/>                    
            </ItemTemplate>                
            <ItemStyle HorizontalAlign="Center"></ItemStyle>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Delete" >
            <ItemTemplate>
                <asp:ImageButton runat="server" ID="Delete" ImageUrl = "../img/cross.png" ToolTip="Delete Account" CommandName="Delete_Account" CommandArgument='<%#((BillingEntity)Container.DataItem).Id %>' OnClientClick="if (confirm('Invoices associated with this account will be deleted permanently. Are you sure you want to delete this account?')==false) {return false;}" />
            </ItemTemplate>                
            <ItemStyle HorizontalAlign="Center"></ItemStyle>
        </asp:TemplateField>            
       <asp:TemplateField HeaderText="View Invoices" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:HyperLink runat="server" ID="ViewInvoiceLink" ToolTip="Recent invoices" NavigateUrl='<%# GetViewInvoiceURL(((BillingEntity)Container.DataItem).Id) %>' >
                    <img src="../img/go.png" border="0"/>
                </asp:HyperLink>
            </ItemTemplate>

            <ItemStyle HorizontalAlign="Center"></ItemStyle>
        </asp:TemplateField>            
       <asp:TemplateField HeaderText="Submit Invoice" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:HyperLink runat="server" ID="InvoiceLink"  ToolTip="Submit invoice" NavigateUrl='<%# GetSubmitInvoiceURL(((BillingEntity)Container.DataItem).Id) %>' >
                    <img src="../img/go.png" border="0"/>
                </asp:HyperLink>
            </ItemTemplate>

            <ItemStyle HorizontalAlign="Center"></ItemStyle>
        </asp:TemplateField>
</Columns>

EDIT-код источника данных

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="GetAllEntities" 
    TypeName="DataAccessLayer.Repository.BillingEntityRepository">
    <SelectParameters>
        <asp:QueryStringParameter DefaultValue="-1" Name="clientId" 
            QueryStringField="clientId" Type="Int32" />
        <asp:Parameter DefaultValue="Name" Name="sortColumn" Type="String" />
        <asp:Parameter DefaultValue="ASC" Name="sortOrder" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

И мой метод сортировки GridView выглядит следующим образом:

protected void GridView_BillingEntity_Sorting(object sender, GridViewSortEventArgs e)
{
    if (ObjectDataSource1.SelectParameters.Count == 3)
    {
        ObjectDataSource1.SelectParameters[1].DefaultValue = e.SortExpression.ToString();
        ObjectDataSource1.SelectParameters[2].DefaultValue = GetSortDirection(e.SortExpression);

        GridView_BillingEntity.DataBind();

        e.Cancel = true;
    }
}

РЕДАКТИРОВАТЬ - строки глазами пользователя

Вот как пользователь видит строку в браузере. Нажатие кнопки удаления удалит строку и обновит сетку.


person Sai    schedule 03.04.2014    source источник
comment
В вашем событии _Sorting к чему вы привязываете Gridview? Я не вижу настраиваемого источника данных.   -  person Martin Smellworse    schedule 03.04.2014
comment
@MartinSmellworse: я отредактировал свой пост, добавив в него DataSource.   -  person Sai    schedule 03.04.2014
comment
Вы сказали, что они решили удалить? Как они выбирают ряд? есть ли кнопка выбора или другой способ?   -  person R.C    schedule 04.04.2014
comment
@FlopScientist: добавлено изображение, показывающее, как пользователь может выбрать удаление строки. В этом примере у меня одна строка. Когда есть несколько строк, я сортирую по одному из первых 6 столбцов и нажимаю удалить строку. Удаляется случайная строка, отличная от выбранной мной.   -  person Sai    schedule 04.04.2014
comment
Что произойдет, если вы отобразите командный аргумент ImageButton, который выполняет удаление, в метке в той же ячейке? Сохраняет ли он правильное значение при сортировке? Я никогда не видел привязки GridView, как вы это сделали. Я всегда использую DataSet - храните его во ViewState, если он не слишком большой, и меняю SortOrder DataSet перед привязкой данных для каждой сортировки.   -  person Martin Smellworse    schedule 04.04.2014
comment
Возможно, в коде, где вы проверяете CommandName, может быть небольшой промах, чтобы предпринять соответствующее действие, например: Delete_Account   -  person R.C    schedule 04.04.2014
comment
@MartinSmellworse: Да, что интересно, сортировка поддерживает значение CommandArgument. Но когда я отлаживаю свой код обработчика после нажатия кнопки «Удалить», передаваемый аргумент команды отличается от того, что указано в метке!   -  person Sai    schedule 04.04.2014
comment
Точнее. Это то же самое, что значение аргумента команды, которое было в той строке перед сортировкой.   -  person Sai    schedule 04.04.2014
comment
Мне кажется, вы могли дважды привязать сетку. Один раз при каждой обратной передаче и один раз при сортировке. Если ваше удаление происходит между этими двумя привязками данных, это объясняет, почему он выбирает «последний» идентификатор. Редактировать. Я вижу, что кто-то уже высказал такое же предложение.   -  person Martin Smellworse    schedule 04.04.2014


Ответы (1)


При нажатии кнопки «Удалить» загрузка страницы происходит до кода обработчика удаления. Поэтому, если вы привязываете GridView к событию page_load, вы должны выполнять привязку при условии !IsPostBack:

if (!IsPostBack)
{
    GridView1.DataSource = MyDataSource;
    GridView1.DataBind();
}

Потому что, если вы каждый раз привязываете GridView, данные будут загружаться заново, то есть GridView повторно заполняется несортированными данными, тем самым теряя предыдущий порядок сортировки.

person R.C    schedule 03.04.2014