我有这些桌子Pages
,PageVersions
和ElementsOnPageVersions
。
我想一次在一页上展示这一切,在一种可折叠的视图中。
如下所示:
- Version 1
- Version 2
- Version 3
- Version 4
- Element 1
- Element 2
- Element 3
- Version 1
- Version 2
- Version 3
- Version 4
- Element 1
- Element 2
- Version 1
- Element 1
- Version 1
- Element 1
我不知道检索数据并在折叠布局中轻松显示数据的最佳方法是什么。
我会这样做:
在这个时候,我会这样做。但它似乎太重了,而且还需要大量的迭代。
做这件事最好的方法是什么?
发布于 2013-12-16 16:12:00
我会考虑把你的三个不同的项目放到一个单独的自我引用列表中。每个项目都需要一个Id、描述和ParentId。我会为此做一个视图模型。
public class TreeItem {
public int Id {get; set;}
public string Description {get; set;}
public int ParentId {get; set;}
}
这将允许您在webforms中使用asp:TreeView,或者使用jQuery树/ treeview (如果您正在使用MVC )。
发布于 2013-12-16 15:49:38
实际上,我建造了一些非常相似的东西。我可以为您提供HTML源代码,但我需要修改.NET代码,以便在公开发布该源代码之前删除特定于公司的专有信息(加上将其转换为C#)。
不幸的是,对我来说,修改我的需要,这将是几乎一个月后,我才能找到它(由于繁忙的一周前,我们休假2周)。但是您可以查看我的HTML,看看可以从其中重用什么。根据我对您的请求的理解,您将占用我的JavaScript及其功能的大约一半。但是如果我处在你的位置上,我会很感激这段代码可以作为启动程序使用,并放弃我不想要的东西,也许还会添加一些东西。或者你可能只是认为我的代码是垃圾,而根本不使用它。;P
这是我的HTML & JavaScript,您可以使用它运行。它使用ul和ol列表处理节点的折叠和扩展。
<!DOCTYPE HTML>
<html>
<head><title>Oz-Med-Hist-VB</title>
<meta charset='utf-8' />
<meta http-equiv='X-UA-Compatible' content='IE=EmulateIE8' />
<style type='text/css'>
body { background: #CCC; margin-left: 1.5em; }
li { list-style-type: none; text-indent: -38px; }
.emptyGrayBox8 {
background-color: #bbb; /* checked and unchecked background color */
border: 1px solid #777; /* checked and unchecked border width & style & color */
padding: 5.5px; display: inline-block; position: relative; margin: 0 3px; margin-top: 3px;
}
.checkInsideGrayBox:after {
content: 'X';
font-size: 13px;
position: absolute;
top: -2px;
left: 1.5px;
color: #555;
}
.checkInsideGrayBoxInsideLI:after {
content: 'X';
font-size: 13px;
position: absolute;
top: -2px;
left: 39.5px;
color: #555;
}
</style>
<script>
if (navigator.userAgent.indexOf('MSIE 8.') < 0)
{
document.write(
' <style>\n' +
' .checkInsideGrayBox { left: 0.5px; }\n' +
' .checkInsideGrayBoxInsideLI:after { left: 38.5px; }\n' +
' </style>');
}
var dta =
{ 'checkedSubNodeCount--1' : 0
, 'checkedSubNodeCount--19' : 0
, 'checkedSubNodeCount--19-a': 0
, 'checkedSubNodeCount--19-b': 0
, 'checkedSubNodeCount--19-c': 0
, 'checkedSubNodeCount--22' : 0
, 'checkedSubNodeCount--24' : 0
, 'checkedSubNodeCount--25' : 0
, 'checkedSubNodeCount--144' : 0
, 'checkedSubNodeCount--1728': 0
};
function chkBox_click(id) // this gets called when user clicks on checkbox or text to right of checkbox.
{ // when checkbox becomes checked, then associated group also becomes shown.
var chkE = document.getElementById('chkBox--' + id); // CHecKBOX HTML element
var grpE = document.getElementById('grpBox--' + id); // GRouPbox HTML element (UL element)
var isChecked = chkE.checked;
if (isChecked)
{ // if user just checked the checkbox, and ...
if (grpE != null) // if an associated (sub)group exists for this checkbox, ...
{ grpE.style.display = ''; } // then expand/show the group element.
}
setLabelHtm(id);
var pid = getParentID(id); // Parent ID
if (id == null) { return; } // if parent id doesn't exist then we're done here.
// now 'pid' is parent ID of 'id'. for instance:
// when id == '19-a' then pid = '19'
// when id == '19-a-1-' then pid = '19-a'
var h = '';
var maxLoopCount = 12; // infinite loop protection :P
while (pid != null && --maxLoopCount >= 0)
{
chkE = document.getElementById('chkBox--' + pid); // CHecKBOX element *of parent*
var pKey = 'checkedSubNodeCount--' + pid; // Key for this Parent ID
if (isChecked) { ++dta[pKey]; } else { --dta[pKey]; }
setLabelHtm(pid);
if (h.length > 0) { h += '\n\n'; }
h += 'id = ' + id + ' isChecked = ' + isChecked
+ '\npid = ' + pid + ' chkE = ' + chkE
+ '\ndta[\'' + pKey + '\'] = ' + dta[pKey];
pid = getParentID(pid);
}
// alert(h);
} // function chkBox_click(id)
function chkBox_click8(id)
{
var chkE = document.getElementById('chkBox--' + id); // CHecKBOX element
var lblE = document.getElementById('chkLab--' + id); // CHecKbox LABel (HTML 'label' element for the checkbox)
if (chkE == null || lblE == null) { return; }
var isChecked = chkE.checked;
var g = Number(chkE.tag);
if (isChecked == false) { g = 3; chkE.tag = g; }
if (isChecked == true ) { g = 2; chkE.tag = g; }
alert(id + '\nisChecked = ' + isChecked + '\n.tag = ' + g);
} // function chkBox_click8(id)
function chkBox_clickIt(id)
{ var chkE = document.getElementById('chkBox--' + id); // CHecKBOX HTML element
if (chkE != null) { chkE.click(); }
} // function chkBox_clickIt(id)
function getParentID(id)
{
var pid = String(id); if (pid.length < 1) { return null; }
if (pid[pid.length - 1] == '-') { pid = pid.substr(0, pid.length - 1); }
var x = pid.lastIndexOf('-'); if (x < 0) { return null; }
pid = pid.substr(0, x); // now pid is id of parent
return pid;
} // function getParentID(id)
function hdrLab_click(id) // this will switch whether the associated group is hidden or shown
{// var chkE = document.getElementById('chkBox--' + id); // CHecKBOX HTML element
var grpE = document.getElementById('grpBox--' + id); // GRouPBOX HTML element (UL element)
if (grpE != null)
{ if (grpE.style.display == '')
{ grpE.style.display = 'none'; }
else
{ grpE.style.display = ''; }
}
setLabelHtm(id);
} // function hdrLab_click(id)
function setLabelHtm(id)
{ var grpE = document.getElementById('grpBox--' + id); // GRouPBOX HTML element (UL element)
var lblE = document.getElementById('hdrLab--' + id);
if (lblE == null) { return; }
var h = null; var suffix = '.';
if (grpE == null) { h = '<span style="visibility: hidden">+</span>'; }
else
{ var grpIsOpen = grpE.style.display == '';
h = '<b>' + (grpIsOpen ? '−' : '+') + '</b>';
}
var s = String(id);
if (s.length > 0 && s.substr(s.length - 1) == '-') { s = '•'; suffix = ''; }
else
{
var x = s.lastIndexOf('-') + 1;
if (x > 0) { s = s.substr(x); }
}
h += ' ' + s + suffix;
var cnt = dta['checkedSubNodeCount--' + id]; // CouNT of checked sub-nodes
if (cnt != null) // if this node is a parent node
{ var chkE = document.getElementById('chkBox--' + id); // CHecKBOX HTML element
if (chkE != null) { chkE.style.display = (cnt > 0) ? 'none' : ''; }
var hBeg = '<span class="emptyGrayBox8">';
var hEnd = '</span>';
if (cnt > 0) { h += hBeg + '<span class="checkInsideGrayBoxInsideLI"></span>' + hEnd; }
else if (chkE == null) { h += hBeg + hEnd; }
}
lblE.innerHTML = h;
} // function setLabelHtm(id)
function init()
{ //alert('yes');
hdrLab_click('1');
hdrLab_click('1-a');
hdrLab_click('19');
hdrLab_click('19-a');
hdrLab_click('19-a-1-');
hdrLab_click('19-a-2-');
hdrLab_click('19-b');
hdrLab_click('19-b-1-');
hdrLab_click('19-b-2-');
hdrLab_click('19-b-3-');
hdrLab_click('19-c');
hdrLab_click('19-c-1-');
hdrLab_click('19-c-2-');
hdrLab_click('19-c-3-');
hdrLab_click('22');
hdrLab_click('22-a');
hdrLab_click('22-b');
hdrLab_click('23');
hdrLab_click('24');
hdrLab_click('24-a');
hdrLab_click('24-b');
hdrLab_click('24-c');
hdrLab_click('25');
hdrLab_click('25-a-');
hdrLab_click('144');
hdrLab_click('144-a');
hdrLab_click('1728');
hdrLab_click('1728-a');
// alert(dta['checkedSubNodeCount--19-a']);
}
window.onload = init;
</script>
</head>
<body>
<ul style='list-style-type: none; margin-left: -1em'>
<li><label id='hdrLab--1' onclick='hdrLab_click("1")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--1' onclick='hdrLab_click("1")')> Test for short number '1':</label></li>
<ul id='grpBox--1'>
<li><label id='hdrLab--1-a' onclick='hdrLab_click("1-a")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--1-a' onclick='chkBox_click("1-a");' /><label id='txtLab--1-a' onclick='chkBox_clickIt("1-a")')>Test for short number '1' subitem:</label></li>
</ul>
<li><label id='hdrLab--19' onclick='hdrLab_click("19")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--19' onclick='hdrLab_click("19")')> Which fruit do you prefer?</label></li>
<ul id='grpBox--19'>
<li><label id='hdrLab--19-a' onclick='hdrLab_click("19-a")' tabindex='0' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-a' onclick='chkBox_click("19-a");' /><label id='txtLab--19-a' onclick='chkBox_clickIt("19-a")')>Apples:</label></li>
<ul id='grpBox--19-a'>
<li><label id='hdrLab--19-a-1-' onclick='hdrLab_click("19-a-1-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-a-1-' onclick='chkBox_click("19-a-1-");' /><label id='txtLab--19-a-1-' onclick='chkBox_clickIt("19-a-1-")')>Red delicious</label></li>
<li><label id='hdrLab--19-a-2-' onclick='hdrLab_click("19-a-2-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-a-2-' onclick='chkBox_click("19-a-2-");' /><label id='txtLab--19-a-2-' onclick='chkBox_clickIt("19-a-2-")')>Granny smith</label></li>
</ul>
<li><label id='hdrLab--19-b' onclick='hdrLab_click("19-b")' tabindex='0' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-b' onclick='chkBox_click("19-b");' /><label id='txtLab--19-b' onclick='chkBox_clickIt("19-b")')>Bananas:</label></li>
<ul id='grpBox--19-b'>
<li><label id='hdrLab--19-b-1-' onclick='hdrLab_click("19-b-1-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-b-1-' onclick='chkBox_click("19-b-1-");' /><label id='txtLab--19-b-1-' onclick='chkBox_clickIt("19-b-1-")')>Green</label></li>
<li><label id='hdrLab--19-b-2-' onclick='hdrLab_click("19-b-2-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-b-2-' onclick='chkBox_click("19-b-2-");' /><label id='txtLab--19-b-2-' onclick='chkBox_clickIt("19-b-2-")')>Yellow (ripe but not too ripe)</label></li>
<li><label id='hdrLab--19-b-3-' onclick='hdrLab_click("19-b-3-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-b-3-' onclick='chkBox_click("19-b-3-");' /><label id='txtLab--19-b-3-' onclick='chkBox_clickIt("19-b-3-")')>Brown (<i>very</i> ripe)</label></li>
</ul>
<li><label id='hdrLab--19-c' onclick='hdrLab_click("19-c")' tabindex='0' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-c' onclick='chkBox_click("19-c");' /><label id='txtLab--19-c' onclick='chkBox_clickIt("19-c")')>Juice</label></li>
<ul id='grpBox--19-c'>
<li><label id='hdrLab--19-c-1-' onclick='hdrLab_click("19-c-1-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-c-1-' onclick='chkBox_click("19-c-1-");' /><label id='txtLab--19-c-1-' onclick='chkBox_clickIt("19-c-1-")')>Orange juice</label></li>
<li><label id='hdrLab--19-c-2-' onclick='hdrLab_click("19-c-2-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-c-2-' onclick='chkBox_click("19-c-2-");' /><label id='txtLab--19-c-2-' onclick='chkBox_clickIt("19-c-2-")')>Grape juice</label></li>
<li><label id='hdrLab--19-c-3-' onclick='hdrLab_click("19-c-3-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--19-c-3-' onclick='chkBox_click("19-c-3-");' /><label id='txtLab--19-c-3-' onclick='chkBox_clickIt("19-c-3-")')>Tomato juice</label></li>
</ul>
</ul>
<li><label id='hdrLab--22' onclick='hdrLab_click("22")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--22' onclick='hdrLab_click("22")')> Which juice do you prefer?</label></li>
<ul id='grpBox--22'>
<li><label id='hdrLab--22-a' onclick='hdrLab_click("22-a")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--22-a' onclick='chkBox_click("22-a");' /><label id='txtLab--22-a' onclick='chkBox_clickIt("22-a")')>Apple juice</label></li>
<li><label id='hdrLab--22-b' onclick='hdrLab_click("22-b")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--22-b' onclick='chkBox_click("22-b");' /><label id='txtLab--22-b' onclick='chkBox_clickIt("22-b")')>Orange juice</label></li>
</ul>
<li><label id='hdrLab--23' onclick='hdrLab_click("23")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--23' onclick='chkBox_click("23");' /><label id='txtLab--23' onclick='chkBox_clickIt("23")')>Single checkmark question with no subnodes</label></li>
<li><label id='hdrLab--24' onclick='hdrLab_click("24")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--24' onclick='hdrLab_click("24")')> Best OS?</label></li>
<ul id='grpBox--24'>
<li><label id='hdrLab--24-a' onclick='hdrLab_click("24-a")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--24-a' onclick='chkBox_click("24-a");' /><label id='txtLab--24-a' onclick='chkBox_clickIt("24-a")') style='color:green'>Android!</label></li>
<li><label id='hdrLab--24-b' onclick='hdrLab_click("24-b")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--24-b' onclick='chkBox_click("24-b");' /><label id='txtLab--24-b' onclick='chkBox_clickIt("24-b")') style='color:brown'>Apple</label></li>
<li><label id='hdrLab--24-c' onclick='hdrLab_click("24-c")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--24-c' onclick='chkBox_click("24-c");' /><label id='txtLab--24-c' onclick='chkBox_clickIt("24-c")')>Linux</label></li>
</ul>
<li><label id='hdrLab--25' onclick='hdrLab_click("25")' tabindex='0' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--25' onclick='chkBox_click("25");' /><label id='txtLab--25' onclick='chkBox_clickIt("25")')>Check question with subnode check too.</label></li>
<ul id='grpBox--25'>
<li><label id='hdrLab--25-a-' onclick='hdrLab_click("25-a-")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--25-a-' onclick='chkBox_click("25-a-");' /><label id='txtLab--25-a-' onclick='chkBox_clickIt("25-a-")')>Sub-node check question</label></li>
</ul>
<li><label id='hdrLab--144' onclick='hdrLab_click("144")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--144' onclick='hdrLab_click("144")')> Test for 3-digit number:</label></li>
<ul id='grpBox--144'>
<li><label id='hdrLab--144-a' onclick='hdrLab_click("144-a")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--144-a' onclick='chkBox_click("144-a");' /><label id='txtLab--144-a' onclick='chkBox_clickIt("144-a")')>Test for 3-digit number subitem:</label></li>
</ul>
<li><label id='hdrLab--1728' onclick='hdrLab_click("1728")' tabindex='0' onkeypress='this.click(); return false;'></label><label id='txtLab--1728' onclick='hdrLab_click("1728")')> Test for 4-digit number:</label></li>
<ul id='grpBox--1728'>
<li><label id='hdrLab--1728-a' onclick='hdrLab_click("1728-a")' onkeypress='this.click(); return false;'></label><input type='checkbox' id='chkBox--1728-a' onclick='chkBox_click("1728-a");' /><label id='txtLab--1728-a' onclick='chkBox_clickIt("1728-a")')>Test for 4-digit number subitem:</label></li>
</ul>
</ul>
<div style='display: none'>
<script>
var ua = navigator.userAgent;
var ieVersion = null;
var ix = 0;
for (var v = 7; v <= 99; v++)
{
document.write('<!--[if IE ' + v + ']><hr />According to the conditional comment this is IE ' + v + '.<![endif]-->');
if ((ix = ua.indexOf('MSIE ' + v + '.')) >= 0)
{ ieVersion = '';
ix += 5;
while (ix < ua.length && '1234567890.'.indexOf(ua.charAt(ix)) >= 0)
{ ieVersion += ua.charAt(ix++);
} document.write('<hr />According to JavaScript, this is IE ' + ieVersion);
}
}
if (ieVersion == null)
{ document.write('<hr />According to JavaScript, this IE version could not be determined.');
} document.write('<hr />navigator.userAgent = ' + navigator.userAgent);
</script><hr />
<button id='webBtn1'>Fire an event</button>
<button id='btnHi' onclick='window.external.sayHelloFromJavaScript("Hello from JavaScript!", 5);'>Say Hello</button>
</div>
</body>
</html>
我还注意到,我的项目使用了一个为IE构建的WebControl,它需要追溯到WinXP。所以我在使用上受到了限制,因为它必须适用于IE7,但更好的是它可以追溯到WinXP最新的IE工作版本。我还关心使用符合标准的代码,因此据我所知,我的JavaScript也适用于任何符合标准的浏览器。我在最新版本的Chrome和FF,IE10,IE8和IE7中测试了它。
仍然需要大量代码将数据生成到HTML页面,但这可以解决一半的请求。
在我的.NET代码中,我必须构建那些JavaScript和HTML,几周后我就可以给出它们了。
发布于 2013-12-19 13:17:41
您可以使用Dictionary对象来填充分层数据。此代码示例可能会有所帮助:
Dictionary<string, Dictionary<string, List<string>>> dictPage = new Dictionary<string, Dictionary<string, List<string>>>();
foreach (DataRow row in dt.Rows)
{
string sPageID = row["PageName"].ToString();
string sVersionID = row["VersionName"].ToString();
string sElementID = row["ElementName"].ToString();
if (!dictPage.ContainsKey(sPageID))
dictPage.Add(sPageID, new Dictionary<string, List<string>>());
if (!dictPage[sPageID].ContainsKey(sVersionID))
dictPage[sPageID].Add(sVersionID, new List<string>());
dictPage[sPageID][sVersionID].Add(sElementID);
}
我在这个示例代码中使用了DataTable
,但您也可以在SqlDataReader
中使用。
要创建HTML,您可以这样做:
StringBuilder sbHtmlUL = new StringBuilder();
sbHtmlUL.Append("<ul>");
foreach (var page in dictPage)
{
sbHtmlUL.Append("<li>");
sbHtmlUL.Append(page.Key);
sbHtmlUL.Append("<ul>");
foreach (var version in page.Value)
{
sbHtmlUL.Append("<li>");
sbHtmlUL.Append(version.Key);
sbHtmlUL.Append("<ul>");
foreach (var element in version.Value)
{
sbHtmlUL.Append("<li>");
sbHtmlUL.Append(element);
sbHtmlUL.Append("</li>");
}
sbHtmlUL.Append("</ul>");
sbHtmlUL.Append("</li>");
}
sbHtmlUL.Append("</ul>");
sbHtmlUL.Append("</li>");
}
sbHtmlUL.Append("</ul>");
在此过程中,还可以应用CSS类、In或简单JavaScript添加折叠/展开行为。
请注意,我并没有将这段代码的性能与其他方法进行比较,所以我不太确定,但在一台平均一台机器上,测试需要8ms才能处理8000条记录。
https://stackoverflow.com/questions/20538481
复制相似问题