2009-10-12 221 views
2

我正在使用c#.net。c#.net ListView - 從不同的表中取回不同的信息

我一直在尋找網絡,找不到任何幫助我的東西。

我有一個承包商名單,每天小時,每天插槽(三個不同的表格)。

  • 第一行 - 包含承包商 名稱。
  • 第二行 - 無限 - 包含 插槽。

例如

alt text

我想我可以用一個ListView但我無法工作了,我會放置代碼。

<asp:ListView ID="contractorListView" runat="server"> 
    <LayoutTemplate> 
    <table runat="server"> 
    <tr> 
    <td>Times</td> 
    // Contractors names pulled from another 
    <th><asp:PlaceHolder id="itemPlaceholder" runat="server" /></th> 
     </tr> 
    </LayoutTemplate> 
    <ItemTemplate> 
    <tr> 
    <td>Times pulled from one database table</td> 
    <td align="left" style="width: 200px;"> 
    // Customers name - attached to correct time 
    <asp:Label runat="server" Text='<%#Eval("person_name")%>' /> 
    </td> 
    </tr> 
    </ItemTemplate> 
    </asp:ListView> 

使用LINQ模型,以便可以連接到客戶的分段時間「

  ObjectDataSource contractorDataSource = new ObjectDataSource(); 
      contractorDataSource.SelectMethod = "GetContractorByDateCategory"; 
      contractorDataSource.TypeName = "contractBook.classes.contractorRepository"; 

      contractorListView.DataSource = contractorDataSource; 

      contractorDataSource.DataBind(); 
      contractorListView.DataBind(); 

任何人有任何想法/例子嗎?

在此先感謝您的幫助。

克萊爾

+0

我不太瞭解你的問題。你有你的數據嗎?你知道如何把它放在ListView中嗎?你的意思是放在哪裏?無論你想要ListView是什麼。 – Letterman 2009-10-17 03:03:56

回答

4

以下是我傾向於解決問題是這樣的:

  • 手動拉我們要顯示的數據(調用庫方法,不使用的ObjectDataSource這樣做)。爲了提高效率,一個大查詢返回非規格化記錄通常很有意義,每個記錄包含所有需要的列(例如:SELECT TimeSlot, CustomerName, ContractorName FROM (joins go here) ...

  • 創建一個自定義集合類,它將數據放入一個簡單的格式到數據綁定。 「易於數據綁定」通常意味着數據的組織順序與您要顯示的順序相同。您也可能需要進行黑客行爲,例如,使所有行的長度相同,以便每行綁定相同數量的表格單元格。

  • 在您的數據綁定表達式中,將Container.DataItem轉換爲您需要的任何類型,以便提取該類型的屬性。這還具有在編譯時使用拼寫錯誤的數據綁定表達式失敗的附加優勢,而不是等到運行時才能找到錯誤。

  • 嵌套,嵌套模板控制(如:中繼器)的DataSource屬性設置爲父母的財產的Container.DataItem

  • 爲標題行,這裏有一個竅門:將頭碼直接進入ItemTemplate,並使用Container.ItemIndex == 0知道何時顯示標題行。由於只有Repeater(但不是ListView)支持ItemIndex屬性,因此我傾向於使用Repeater而不是ListView來執行大多數只讀數據綁定任務。這就是爲什麼我在下面的代碼示例中更改了您的ListView以使用Repeater。將Index或RowNumber屬性添加到上述自定義數據綁定類中也可以做到這一點,但這很難。

總的想法是,你要推的大量情報,儘可能出你的數據綁定代碼並進入你的頁面的實際方法(或代碼隱藏)代碼,這是更容易編寫和調試。

下面是一個工作示例(將您的類和存儲庫類嘲笑起來),讓您知道我在說什麼。你應該能夠適應你的情況。

<%@ Page Language="C#"%> 
<%@ Import Namespace="System.Collections.Generic" %> 
<%@ Import Namespace="System.Linq" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<script runat="server"> 
    public class Person // replace with your class 
    { 
     public string person_name {get; set;} 
    } 
    public class Repository // replace with your class 
    { 
     public static IEnumerable<Record> GetCustomerByDateCategory() 
     { 
      // fake some data 
      return new Record[] 
      { 
       new Record { Time = new DateTime(2000, 1, 1, 8, 0, 0), Contractor = new Person {person_name = "Joe the Plumber"}, Customer = new Person {person_name = "Joe Smith"} }, 
       new Record { Time = new DateTime(2000, 1, 1, 8, 30, 0), Contractor = new Person {person_name = "Bob Vila"}, Customer = new Person {person_name = "Frank Johnson"} }, 
       new Record { Time = new DateTime(2000, 1, 1, 8, 30, 0), Contractor = new Person {person_name = "Mr. Clean"}, Customer = new Person {person_name = "Elliott P. Ness"} }, 
      }; 
     } 
     public class Record // replace this class with your record's class 
     { 
      public DateTime Time {get; set;} 
      public Person Contractor { get; set; } 
      public Person Customer { get; set; } 
     } 
    } 

    // key = time, value = ordered (by contractor) list of customers in that time slot 
    public class CustomersByTime : SortedDictionary<DateTime, List<Person>> 
    { 
     public List<Person> Contractors { get; set; } 

     public CustomersByTime (IEnumerable <Repository.Record> records) 
     { 
      Contractors = new List<Person>(); 
      foreach (Repository.Record record in records) 
      { 
       int contractorIndex = Contractors.FindIndex(p => p.person_name == record.Contractor.person_name); 
       if (contractorIndex == -1) 
       { 
        Contractors.Add(record.Contractor); 
        contractorIndex = Contractors.Count - 1; 
       } 
       List<Person> customerList; 
       if (!this.TryGetValue(record.Time, out customerList)) 
       { 
        customerList = new List<Person>(); 
        this.Add(record.Time, customerList); 
       } 
       while (customerList.Count < contractorIndex) 
        customerList.Add (null); // fill in blanks if needed 
       customerList.Add (record.Customer); // fill in blanks if needed 
      } 
      MakeSameLength(); 
     } 
     // extend each list to match the longest one. makes databinding easier. 
     public void MakeSameLength() 
     { 
      int max = 0; 
      foreach (var value in this.Values) 
      { 
       if (value.Count > max) 
        max = value.Count; 
      } 
      foreach (var value in this.Values) 
      { 
       while (value.Count < max) 
        value.Add(null); 
      } 
     } 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     CustomersByTime Customers = new CustomersByTime(Repository.GetCustomerByDateCategory()); 
     CustomerListView.DataSource = Customers; 
     CustomerListView.DataBind(); 
    } 
</script> 
<html> 
<head> 
<style type="text/css"> 
    td, th, table { border:solid 1px black; border-collapse:collapse;} 
</style> 
</head> 
<body> 
    <asp:Repeater ID="CustomerListView" runat="server"> 
    <HeaderTemplate><table cellpadding="2" cellspacing="2"></HeaderTemplate> 
    <ItemTemplate> 
     <asp:Repeater runat="server" visible="<%#Container.ItemIndex==0 %>" 
      DataSource="<%#((CustomersByTime)(CustomerListView.DataSource)).Contractors %>" > 
      <HeaderTemplate> 
      <tr> 
       <th>Times</th> 
      </HeaderTemplate> 
      <ItemTemplate> 
      <th><%#((Person)Container.DataItem).person_name %></th> 
      </ItemTemplate> 
      <FooterTemplate>    
      </tr> 
      </FooterTemplate> 
     </asp:Repeater> 
     <tr> 
     <td><%#((KeyValuePair<DateTime, List<Person>>)(Container.DataItem)).Key.ToShortTimeString() %></td> 
     <asp:Repeater ID="Repeater1" runat="server" DataSource="<%# ((KeyValuePair<DateTime, List<Person>>)(Container.DataItem)).Value %>"> 
      <ItemTemplate> 
      <td align="left" style="width: 200px;"> 
       <%#Container.DataItem == null ? "" : ((Person)(Container.DataItem)).person_name%> 
      </td> 
      </ItemTemplate> 
     </asp:Repeater> 
     </tr> 
    </ItemTemplate> 
    <FooterTemplate></table></FooterTemplate> 
    </asp:Repeater> 
</body> 
</html> 

順便說一句,如果你正在構建一個全新的應用程序,並有一定的學習時間,我肯定建議尋找ASP.NET MVC,其中有一個不平凡的學習曲線,但使得很多事情更簡單...在partiuclar這種複雜的數據渲染。

+0

+1推薦ASP.NET MVC! :-) – Sergio 2009-10-19 17:33:14

0

爲什麼不創建,提取所有信息的單個查詢?

您可以對多個表執行JOIN操作。

如果聯接變得非常複雜,您可以創建一個VIEW,它將創建一個新的虛擬表來整合您的信息。