2010-01-19 27 views
6

Tôi có một nguồn đối tượng mà tôi muốn liên kết với bộ lặp. vấn đề là, tôi không thể tìm ra cách hiển thị số lượng cột thay đổi với số lượng hàng biến đổi.Các cột lặp biến thiên

ví dụ:

Tập dữ liệu tôi có được cấu trúc như thế này. Objectdatasource là List<item>.

item { 
    string name; 
    List<itemdata> data; 
} 

itemdata { 
    DateTime year; 
    double amount; 
} 

nên về cơ bản tôi muốn làm một bảng

 | year | year | year | year 
name | amount | amount | amount | amount 
name | amount | amount | amount | amount 
name | amount | amount | amount | amount 
name | amount | amount | amount | amount 

Số lượng các mục là biến, cũng như số lượng ItemData rằng mục chứa.

Hy vọng ai đó có thể chỉ cho tôi đúng hướng.

Cảm ơn

+0

Tôi có thể đặt bộ lặp lồng nhau vào thẻ không? – Mike

Trả lời

6

Giải pháp cho vấn đề của bạn sẽ yêu cầu ba lặp khác nhau, một trong số đó được lồng vào bên trong khác. Bắt đầu với đánh dấu như thế này.

<table> 
     <tr class="headerRow"> 
      <td> &nbsp;</td> 
      <asp:Repeater ID="rptYearHeader" runat="server" OnItemDataBound="rptYearHeader_ItemDataBound"> 
       <ItemTemplate> 
       <td class="header"><asp:Literal ID="litYear" runat="server"></asp:Literal></td> 
       </ItemTemplate> 
      </asp:Repeater> 
     </tr> 
     <asp:Repeater ID="rptName" runat="server" ItemDataBound="rptName_ItemDataBound"> 
      <ItemTemplate> 
      <tr> 
       <td><asp:Literal ID="litName" runat="server"></asp:Literal></td> 
       <asp:Repeater ID="rptAmounts" runat="server" OnItemDataBound="rptAmounts_ItemDataBound"> 
       <ItemTemplate> 
       <td><asp:Literal ID="litAmount" runat="server"></asp:Literal></td> 
       </ItemTemplate> 
      </asp:Repeater> 
      </tr> 
      </ItemTemplate> 
     </asp:Repeater> 
    </table> 

Việc liên kết này có thể hơi phức tạp một chút. Ý tưởng là, trước tiên chúng tôi ràng buộc hàng tiêu đề - sau đó chúng tôi ràng buộc các hàng dữ liệu và trên các cột. Bạn sẽ muốn xử lý các ràng buộc dữ liệu thông qua mã phía sau bằng cách sử dụng sự kiện OnItemDataBound để bạn có thể kết nối bộ lặp lồng nhau với các dữ liệu cần thiết.

Trước tiên, chúng tôi ràng buộc hàng tiêu đề bằng Năm. Bạn cần cô lập một tập hợp các năm duy nhất có trong nguồn dữ liệu của bạn và giữ nó trong một biến riêng tư. Bạn sẽ cần phải truy cập nó trong quá trình kết nối dữ liệu của các bộ lặp khác sau này. Điều này sẽ đóng vai trò là nguồn dữ liệu cho hàng tiêu đề, tạo một ô/cột cho mỗi năm.

List<DateTime> _Years = dataSource.SelectMany(x => x.data).GroupBy(y => y.Year); 
rptYear.DataSource = _Years; 
rptYear.DataBind(); 

Bây giờ, bạn cần phải ràng buộc bộ lặp tên với nguồn dữ liệu gốc của bạn. Một cái gì đó như

rptName.DataSource = dataSource; 
rptName.DataBind(); 

Điều này sẽ tạo một hàng cho mỗi mục trong danh sách của bạn. Trong sự kiện OnItemDataBound cho repeater này, bạn sẽ cần phải ràng buộc repeater lồng nhau vào danh sách các năm tài chính - mỗi một năm tài chính trong biến _Years của chúng tôi - với bất kỳ dữ liệu áp dụng nào từ mục dữ liệu của hàng hiện tại. Điều này hơi phức tạp, nhưng tôi sẽ cố gắng giải thích:

protected void rptName_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
// get the data item being bound 
item currentItem = e.Item.DataItem as item; 

// bind the item's name to the literal 
//... 
// 

// get a list of amounts to bind to the nested repeater 
// because we cant be sure that every item has amount for all years 
// we create a list that we know has all years and plug in the items 
// data accordingly. 

    List<double> amounts = new List<double>(); 
    for (int i = 0; i < _Years.Count; i++) 
    { 
     // check whether the current item has data for the year 
     dataItem di = currentItem.data.Where(d => d.Year == _Years[i]).FirstOrDefault(); 

     if(di == null) 
     { 
      // the year did not exist, so we add an amount of 0 
      amounts.Add(0); 
     } 
     else 
     { 
      // the year did exist, so we add that year's amount 
      amounts.Add(di.amount); 
     } 
    } 

    // we now have a list of amounts for all possible years, with 0 filling in 
    // where the item did not have a value for that year 

    // bind this to the nested repeater 
    rptAmounts.DataSource = amounts; 
    rptAmounts.DataBind(); 

} 

Chúc may mắn.

Tôi đã phải tắt chức năng này với nhiều bộ lặp lồng nhau cho tổng số phụ và tổng số hàng trước đó. Tôi bắt đầu thấy những người lặp lại lồng nhau trong giấc ngủ của tôi.

+1

Đây là phản ứng tuyệt vời. Nó đã làm việc. Cảm ơn nhiều. Tôi nghĩ tôi cũng bắt đầu thấy những người lặp lại lồng nhau trong giấc ngủ của tôi. : P – Mike

0

Tôi đề nghị bạn chuyển đổi dữ liệu của bạn thành một cấu trúc dữ liệu mới như thế này:.

name_data { 
    string name; 
    int[] amounts; 
} 

Sau đó, bạn sẽ ràng buộc lặp lại của bạn vào một danh sách (name_data>

Để tạo này , trước hết, hãy lặp qua các danh sách itemdata và giữ một danh sách (một Danh sách có thể) của tất cả các năm duy nhất bạn cần báo cáo. Sắp xếp danh sách kết quả để các năm theo thứ tự. ond đến các số cột trong bảng đầu ra của bạn. Tiếp theo, lặp lại thông qua danh sách item, lần này tạo đối tượng name_data mới cho mỗi đối tượng item. Trình tạo tên name_data sẽ trông giống như sau:

public name_data(string name, int yearCount) { 
    this.name = name; 
    amounts = new int[yearCount]; 
} 

NămCount là số mục trong danh sách năm.

Cuối cùng, hãy duyệt qua danh sách data cho số item hiện tại, tra năm trong danh sách năm để lấy chỉ mục, sau đó dán giá trị số tiền vào trường số tiền trong khe amounts tương ứng. Thêm tên đã hoàn thành của bạn vào Danh sách.

Khi bạn làm xong, bạn sẽ có thể để ràng buộc danh sách name_data của bạn để lặp lại của bạn

+0

Tôi không chắc cấu trúc đó có hiệu quả với anh ta hay không. Trong cấu trúc của mình, anh ta có thể gán một số tiền cho một năm ở giữa, nơi bạn sẽ giả định rằng tất cả các mục đều có dữ liệu theo thứ tự thích hợp. –

+0

Có, trong câu trả lời của bạn, nó đòi hỏi mọi thứ đều theo thứ tự và sắp xếp. Trong trường hợp của tôi có những lúc nó không theo thứ tự. – Mike

+0

Đây là lý do tại sao tôi đề nghị một lần đầu tiên vượt qua các dữ liệu để lấy những năm và sắp xếp chúng. Đợt thứ hai để gán dữ liệu cho cột thích hợp. – Ray

Các vấn đề liên quan