我正在使用c#.net。
我一直在寻找网络,找不到任何可以帮助我的东西。
我有一份承包商名单,每日营业时间,每日广告位(三张不同的牌桌)。
例如
我以为我可以使用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 :(得分: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属性可以完成同样的事情,但这更难。
一般的想法是,你想尽可能多地将你的数据绑定代码 out 推送到你的页面(或代码隐藏)代码中的实际方法中,这些代码更易于编写和调试。
这是一个工作示例(你的类和存储库类被模拟),让你知道我在说什么。你应该能够适应你的情况。
<%@ 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中这种复杂的数据渲染。
答案 1 :(得分:0)
这不仅仅是一个交叉标签的情况吗?看看我的解决方案:
Cross Tab - Storing different dates (Meeting1, Meeting2, Meeting 3 etc) in the same column
答案 2 :(得分:0)
为什么不创建一个提取所有信息的查询?
您可以对多个表执行JOIN操作。
如果连接变得非常复杂,您可以创建一个VIEW,它会创建一个新的虚拟表来整合您的信息。