Общая сумма столбца ListView и отображение в метке возвращает значение null

Я пытаюсь суммировать все значения из столбца июля в метку с идентификатором июля. Вот разметка:

<asp:ListView ID="leaveListView" runat="server" ItemPlaceholderID="itemPlaceholder" OnItemDataBound="leaveListView_ItemDataBound">
    <LayoutTemplate>
        <table class="budgetList">
            <thead>
                <tr>
                    <td>Project Number</td>
                    <td>Account</td>
                    <td>Project Name</td>
                    <td>July</td>
                </tr>
            </thead>
            <tbody>
                <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
            </tbody>
            <tfoot>
                <tr class="projectRowTotal">
                    <td>Project Totals</td>
                    <td></td>
                    <td></td>
                    <td><asp:Label ID="july" runat="server" Text=""></asp:Label></td>
                </tr>
            </tfoot>
        </table>
    </LayoutTemplate>
    <ItemTemplate>
        <tr class="<%# Container.DataItemIndex % 2 == 0 ? "" : "even" %>">
            <td><%# Eval("Project") %></td>
            <td><%# Eval("Account") %></td>
            <td><%# Eval("ProjectNumber") %></td>
            <td><%# Eval("July") %></td>
        </tr>
    </ItemTemplate>
</asp:ListView>

Я использую событие ItemDataBound для суммирования, но оно возвращает null. Это код позади:

decimal july = 0m;
protected void leaveListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
            july += Convert.ToDecimal(e.Item.FindControl("July"));            
    }
    Label julySum = (Label)leaveListView.FindControl("july");
    julySum.Text = string.Format("{0:C}", (decimal?)july);
}

Что мне нужно сделать, чтобы заставить это работать?


person psdpainter    schedule 21.11.2013    source источник
comment
почему бы не использовать метод linq Sum и просто привязаться к нему?   -  person Noctis    schedule 22.11.2013
comment
Это в Layout-, а не в ItemTemlate, поэтому вам не нужно leaveListView.FindControl вместо e.Item.FindControl? В вашем ItemTemplate вообще нет управления с ID.   -  person Tim Schmelter    schedule 22.11.2013
comment
Так я использую событие LayoutCreated?   -  person psdpainter    schedule 22.11.2013
comment
на самом деле вы можете сделать это и так: ‹table›thead /›‹ListView /›‹tfoot /›‹/table›, теперь у вас есть прямой доступ к Label из кода. Но, как было предложено, вы создаете строки на основе некоторых данных, почему бы вам не сделать сумму в коде и просто не поставить july.Text = ‹value› ... тоже (в коде, где вы связываете данные)?   -  person frno    schedule 22.11.2013
comment
кроме того, вы можете полностью удалить leaveListView_ItemDataBound   -  person frno    schedule 22.11.2013


Ответы (2)


как предложили мои комментарии, вот решение:

<table class="budgetList">
   <thead>
       <tr>
           <td>Project Number</td>
           <td>Account</td>
           <td>Project Name</td>
           <td>July</td>
       </tr>
   </thead>
   <tbody>
   <asp:ListView ID="leaveListView" runat="server" ItemPlaceholderID="itemPlaceholder">
       <LayoutTemplate>
           <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
       </LayoutTemplate>
       <ItemTemplate>
        <tr class="<%# Container.DataItemIndex % 2 == 0 ? "" : "even" %>">
           <td><%# Eval("Project") %></td>
           <td><%# Eval("Account") %></td>
           <td><%# Eval("ProjectNumber") %></td>
           <td><%# Eval("July") %></td>
        </tr>
       </ItemTemplate>
   </asp:ListView>
   </tbody>
        <tfoot>
            <tr class="projectRowTotal">
                <td>Project Totals</td>
                <td></td>
                <td></td>
                <td><asp:Label ID="july" runat="server" Text=""></asp:Label></td>
            </tr>
        </tfoot>
    </table>

на самом деле не пробовал, но должно работать нормально... + в коде, где вы связываете данные:

 leaveListView.ItemsSource = <data>;
 // simply place the value in label directly
 july.Text = <data.sum>

теперь просто сделайте сумму в коде, и все готово, нет необходимости в событии itemdatabound

person frno    schedule 21.11.2013

e.Item.FindControl("July") возвращает значение null, потому что нет элемента управления с существующим в ListView

Решение

Вы хотите сохранить значение July в HiddenField (или в другом поле), чтобы вы могли получить их обратно в событии ItemDataBound.

<asp:ListView ID="leaveListView"...>
    <ItemTemplate>
        <tr class="<%# Container.DataItemIndex % 2 == 0 ? "" : "even" %>">
            <td><%# Eval("Project") %></td>
            <td><%# Eval("Account") %></td>
            <td><%# Eval("ProjectNumber") %></td>
            <td><%# Eval("July") %></td>
        </tr>
        <asp:HiddenField runat="server" ID="JulyHiddenField" 
           Value="<%# Eval("July") %>"/>
    </ItemTemplate>
</asp:ListView>

decimal july = 0m;
protected void leaveListView_ItemDataBound(object sender, 
  ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        var hiddenField = e.Item.FindControl("JulyHiddenField") as HiddenField;
        july += Convert.ToDecimal(hiddenField.Value);            
    }
    Label julySum = (Label)leaveListView.FindControl("july");
    julySum.Text = string.Format("{0:C}", (decimal?)july);
}

Для хорошей практики проектирования

Пожалуйста, назовите свой элемент управления правильно. Например. <asp:Label ID="JulyLabel" runat="server" Text=""></asp:Label>. В настоящее время у вас нет возможности узнать, что такое july.

person Win    schedule 21.11.2013