2011-12-15 3 views
2

Ситуация: У меня есть несколько Gridviews на одной странице, и у каждого Gridview есть динамически созданная строка, отображающая итоговые значения внизу. В каждом случае строка итогов создается в событии RowDataBound. Стратегия, которую я использую, подобна той, которую предоставил Майк Дуган на своем Blog.Динамически созданные строки исчезают из Gridviews при обновлении/удалении

Ниже приведен код для одного из GridViews, но остальные все делают что-то очень симулятивное.

protected void gvWorkerHours_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    // Keep running total of hours. 
    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     totalBillableHours += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Hours")); 
    } 

    if (e.Row.RowType == DataControlRowType.Footer) 
    { 
     int numColumns = gvWorkerHours.Columns.Count; 
     int hoursIndex = 4; //5th column, 0-based 
     int rowIndex = gvWorkerHours.Rows.Count + 1; 

     CreateTotalRow((Table)e.Row.Parent, rowIndex, totalBillableHours, hoursIndex, numColumns); 
    } 
} 

private void CreateTotalRow(Table table, int rowIndex, double totalValue, int totalIndex, int numColumns) 
{ 
    TableCell[] cells = new TableCell[numColumns]; 
    for (int i = 0; i < numColumns; i++) 
    { 
     TableCell cell = new TableCell(); 
     Label label = new Label(); 
     label.Font.Bold = true; 

     if (i == 0) 
     { 
      label.Text = "Total"; 
     } 
     else if (i == totalIndex) 
     { 
      label.Text = totalValue.ToString(); 
     } 
     else 
     { 
      label.Text = ""; 
     } 

     cell.Controls.Add(label); 
     cells[i] = cell; 
    } 
    GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal); 
    row.Cells.AddRange(cells); 
    table.Rows.AddAt(rowIndex, row); 
} 

Проблема: Если пользователь нажимает на редактирование/удаление команды для любой строки на любой из этих GridViews, он будет делать итоговые строки исчезают для всех остальных GridViews. Насколько я понимаю, это происходит потому, что происходит PostBack, однако события RowDataBound не будут встречаться для других GridView, а они просто перезагружают свои данные из ViewState, которые не содержат итоговые значения.

Неудачные попытки решения: Я не могу просто вызвать DataBind для каждого из GridView во время PostBack, потому что это предотвратит появление обновления/удаления. Хотя событие RowCreated будет происходить для GridViews во время PostBack, этого события недостаточно, потому что GridViews не будет привязан к данным и будет генерировать исключение, когда я попытаюсь вычислить общее количество. Отключение ViewState для этих GridViews похоже на решение, однако будет много данных для перезагрузки при каждом нажатии пользователем команды. Ручное сохранение моих данных в ViewState также похоже на решение, но, похоже, нет простого способа заставить GridViews получить эти пользовательские данные в PostBack.

Есть ли способ достичь того, что я пытаюсь сделать с ASP.NET? Похоже, простое требование иметь итоговую строку в нижней части каждого GridView.

Заранее благодарим за любую помощь.

+0

Вы рассматривали использование ajax или updatepanel только для обновления того, что хотите? –

+0

Я еще не пробовал использовать UpdatePanel, хотя вся страница уже завернута в UpdatePanel, чтобы сохранить позицию прокрутки в PostBacks. Я сделаю это. –

+0

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

ответ

0

ОК, как я в конечном итоге решил это с помощью JQuery. Если кто-то другой сталкивается с подобной проблемой, помните, что итоговые суммы должны вычисляться, когда DOM готов, а также в конце любой обратной передачи. Чтобы справиться с ситуацией обратной передачи, вы можете просто вызвать Javascript на клиенте с помощью ScriptManager.RegisterStartupScript().

Опять же, у меня было четыре GridViews в моем обстоятельстве, но я просто показать код JQuery для одного из них:

$(document).ready(function() { 
    setTotals(); 
}); 

function setTotals() { 

    var totalHours = getBillableHoursTotal(); 
    if (isNaN(totalHours)) totalHours = '...editing'; 
    $('#spanBillableHoursTotal').html(totalHours); 

    //... etc. 
} 

function getBillableHoursTotal() { 
    var total = 0.0; 
    var rows = $('table[id*="_gvWorkerHours"] tr.RegularRows'); 
    $(rows).each(function() { 
     total = total + parseFloat($(this).children('td').children('span[id*="lblHours"]').html()); 
    }); 
    return total; 
} 

А для C# на код позади:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // ... preceeding Page Load code 

    if (IsPostBack) 
    { 
     ScriptManager.RegisterStartupScript(this, this.GetType(), "?", "setTotals()", true); 
    } 
} 
0

Что делать, если вы попытаетесь создать динамическую строку, используя событие gridView.OnPreRender вместо события gridView.RowDataBound. Таким образом, ваши данные, необходимые для расчета ваших результатов динамической строки, доступны, но html еще не отправлен в веб-браузер. Пожалуйста, разместите еще какой-нибудь код, чтобы мы могли лучше понять вашу проблему.

+0

Спасибо за помощь gsirianni. Я редактировал свой оригинальный вопрос, чтобы включить код. Я попробую использовать событие PreRender. –

+0

OK @gsirianni, я попытался сделать это в PreRender, но он сломал все команды (обновить, удалить, вставить). Я отправлю код в другом ответе. –

0

Как и рекомендовалось, я попытался поместить код для создания итоговой строки в событии PreRender, а не в событии RowDataBound. Это, похоже, сработало, за исключением того, что он сломал все команды для GridView, в которых он использовался. Похоже, что ручное изменение GridView нарушает его автоматическое поведение.

protected void gvWorkerHours_PreRender(object sender, EventArgs e) 
{ 
    double total = 0; 
    int numColumns = gvWorkerHours.Columns.Count; 
    int hoursIndex = 4; //5th column, 0-based 
    int rowIndex = gvWorkerHours.Rows.Count + 1; 

    foreach (GridViewRow row in gvWorkerHours.Rows) 
    { 
     if (row.RowType == DataControlRowType.DataRow) 
     { 
      Label label = (Label)row.FindControl("lblHours"); 
      total += Convert.ToDouble(label.Text); 
     } 
    } 

    CreateTotalRow((Table)gvWorkerHours.Rows[0].Parent, rowIndex, total, hoursIndex, numColumns); 
} 
Смежные вопросы