分享
 
 
 

模拟Windows Listview的HTC组件

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

本文属spanzhang原创,其blog地址为:http://blog.csdn.net/spanzhang。引用或转贴请注明出处,谢谢!!

在开发B/S应用时,经常需要以列表的形式显示数据,但HTML的TABLE却显得很不够用。这里给出的是我自己的Listview模拟控件,它主要有如下几个特点:

1、Header和Columns都可以灵活配置;

2、Columns可以拖动;

3、支持单选和多选模式;

4、支持鼠标双击(引发事件)。

效果图如下:

HTC组件源代码如下(htc_listView.htc):

<!--

作者:张友邦

时间:2004-12-01

描述:表格控件

-->

<!--

接口定义

-->

<public:component>

<public:property name="description" value="Span ListView Behavior" />

<public:property name="version" value="1.0.0.0" />

<public:attach event="oncontentready" onevent="init()" />

<public:attach event="onselectstart" onevent="cancelSelect()" />

<public:attach event="onresize" onevent="resize()" />

<public:attach event="onmousemove" onevent="mouseMove()" />

<public:attach event="onmouseup" onevent="mouseUp()" />

<public:property name="headImage" value="/spanClient/htc_listView.htc.res/headerBg.gif" />

<public:property name="splitterImage" value="/spanClient/htc_listView.htc.res/headerSplit.gif" />

<public:property name="defStyle1" value="background-color: #DADFF1" />

<public:property name="defStyle2" value="background-color: #B9C1DD" />

<public:property name="defStyle11" value="background-color: #000000; color: #FFFFFF" />

<public:property name="defStyle22" value="background-color: #000064; color: #FFFFFF" />

<public:property name="singleSelect" value="true" />

<public:property name="freezeCols" value="false" />

<public:property name="header" />

<public:property name="columns" />

<public:property name="dataTable" />

<public:property name="rows" />

<public:property name="selectedRows" />

<public:method name="addColumn" />

<public:method name="addRow" />

<public:method name="delRow" />

<public:method name="selectRow" />

<public:method name="clearSelect" />

<public:event name="onSelChange" id="selChange" />

<public:event name="onWantEdit" id="wantEdit" />

<public:event name="onHeadClick" id="headClick" />

</public:component>

<!--

组件实现

-->

<script language="javascript">

var headerWidth = 0; //表头宽度

var bodySpan = null; //体对象

var downType = -1; //鼠标点下去的类型,点在不同地方会有不同的类型

var objSizeItem = null; //拖动线

//列对象

function column(colHeader, splitter, style1, style2, style11, style22)

{

this.colHeader = colHeader;

this.splitter = splitter;

this.style1 = style1; //第一种未选中样式

if (this.style1 == null) this.style1 = defStyle1;

this.style2 = style2; //第二种未选中样式

if (this.style2 == null) this.style2 = defStyle2;

this.style11 = style11; //第一种选中状态样式

if (this.style11 == null) this.style11 = defStyle11;

this.style22 = style22; //第一种选中状态样式

if (this.style22 == null) this.style22 = defStyle22;

}

//内部函数,事件oncontentready,初始化

function init()

{

var rs = element.children[0].recordset;

//基本属性

columns = new Array();

selectedRows = new Array();

element.style.overflow = "hidden";

//构造表头

header = document.createElement("SPAN");

with (header.style)

{

width = "2048";

height = 20;

backgroundImage = "url(" + headImage + ")";

cursor = "default";

}

element.insertAdjacentElement("beforeEnd", header);

//构造BODY

bodySpan = document.createElement("SPAN");

with (bodySpan.style)

{

overflow = "auto";

cursor = "default";

}

bodySpan.attachEvent("onscroll", bodyScroll);

element.insertAdjacentElement("beforeEnd", bodySpan);

dataTable = document.createElement("TABLE");

with (dataTable)

{

cellSpacing = 0;

cellPadding = 0;

width = 1;

borderColor = "#305D03";

}

bodySpan.insertAdjacentElement("beforeEnd", dataTable);

rows = dataTable.rows;

//拖动线

if (freezeCols == 'false')

{

objSizeItem = window.document.createElement("DIV") ;

with (objSizeItem.style)

{

backgroundColor = "black" ;

cursor = "col-resize";

position = "absolute" ;

border = "none";//"solid 0px" ;

width = "1px" ;

zIndex = 3000 ;

visibility = "hidden" ;

}

window.document.body.insertAdjacentElement("beforeEnd", objSizeItem);

}

//插入所有的列

var style1, style2, style11, style22;

for (var i = 0; rs != null && !rs.EOF; ++i)

{

try {style1 = new String(rs('style1'));} catch(e) {style1 = defStyle1;}

if (style1 == 'null') style1 = defStyle1;

try {style2 = new String(rs('style2'));} catch(e) {style2 = defStyle2;}

if (style2 == 'null') style2 = defStyle2;

try {style11 = new String(rs('style11'));} catch(e) {style11 = defStyle11;}

if (style11 == 'null') style11 = defStyle11;

try {style22 = new String(rs('style22'));} catch(e) {style22 = defStyle22;}

if (style22 == 'null') style22 = defStyle22;

addColumn(rs('width'), rs('text'), style1, style2, style11, style22);

rs.moveNext();

}

//调整布局

resize();

}

//方法,创建列

function addColumn(colWidth, colContent, style1, style2, style11, style22)

{

var colIndex = columns.length;

columns[colIndex] = new column

(

document.createElement("SPAN"),

document.createElement("SPAN"),

style1, style2,

style11, style22

);

//列标题栏

columns[colIndex].colHeader.innerHTML = colContent;

with (columns[colIndex].colHeader.style)

{

width = colWidth;

height = 20;

textAlign = "center";

backgroundImage = "url(" + headImage + ")";

overflow = 'hidden';

headerWidth += parseInt(colWidth) + 4;

}

columns[colIndex].colHeader.onclick = new Function("var eventObject = createEventObject();eventObject.colIndex = "

+ colIndex + ";headClick.fire(eventObject);");

header.insertAdjacentElement("beforeEnd", columns[colIndex].colHeader);

//分隔条

with (columns[colIndex].splitter)

{

position = "absolute" ;

if (freezeCols == 'false')

onmousedown = new Function("splitterDown(" + colIndex + ")");

}

with (columns[colIndex].splitter.style)

{

left = headerWidth - 4;

width = 4;

height = 20;

if (freezeCols == 'false')

cursor = "col-resize";

backgroundImage = "url(" + splitterImage + ")";

}

header.insertAdjacentElement("beforeEnd", columns[colIndex].splitter);

//调整dataTable的宽度

dataTable.width = headerWidth - 2;

}

//内部函数,事件onresize

function resize()

{

with (bodySpan.style)

{

width = parseInt(element.clientWidth);

height = parseInt(element.clientHeight) - 20;

}

}

//内部函数,体滚动事件onscroll

function bodyScroll()

{

header.style.marginLeft = (-window.event.srcElement.scrollLeft) ;

}

//取消选择

function cancelSelect()

{

with (window.event)

{

cancelBubble = true ;

returnValue = false ;

}

return false ;

}

var downSpliterIndex = -1;

var eventX1;

var eventX2;

//内部函数,分隔条点下

function splitterDown(index)

{

with (window.event)

{

eventX1 = parseInt(clientX);

cancelBubble = true;

returnValue = false;

}

element.setCapture();

downSpliterIndex = index;

downType = 1;

with (objSizeItem.style)

{

top = element.offsetTop;

height = element.offsetHeight;

posLeft = window.event.clientX - 3;

visibility = "visible";

}

}

//内部函数,事件onmousemove

function mouseMove()

{

switch (true)

{

case downType == 1:

objSizeItem.style.posLeft = window.event.clientX - 2;

break;

default:

break;

}

}

//内部函数,事件onmouseup

function mouseUp()

{

if (downType == -1)

return;

with (window.event)

{

eventX2 = parseInt(clientX);

cancelBubble = true;

returnValue = false;

}

switch (true)

{

case downType == 1:

var dx = eventX2 - eventX1;

var colWidth = parseInt(columns[downSpliterIndex].colHeader.style.width);

if (colWidth + dx < 1) dx = 1-colWidth;

colWidth += dx;

columns[downSpliterIndex].colHeader.style.width = colWidth;

dataTable.width = parseInt(dataTable.width) + dx;

for (var i = 0; i < rows.length; ++i)

{

//setRowCss(rows[i]);

for (var j = 0; j < columns.length; ++j)

{

if (j == 0)

rows[i].children[j].style.width = parseInt(columns[j].colHeader.style.width) + 2;

else

rows[i].children[j].style.width = parseInt(columns[j].colHeader.style.width) + 4;

}

}

setColWidth();

header.style.marginLeft = (-bodySpan.scrollLeft);

break;

default:

break;

}

element.releaseCapture();

objSizeItem.style.visibility = "hidden";

downType = -1;

}

//行的事件:click

function clickRow(rowIndex)

{

if (!window.event.ctrlKey || singleSelect == 'true')

{

for (var i = 0; i < selectedRows.length; ++i)

{

if (selectedRows[i].rowIndex >= 0)

selectRow(selectedRows[i].rowIndex, false);

}

selectedRows.length = 0;

}

if (rowIndex >= 0)

selectRow(rowIndex, !rows[rowIndex].selected);

}

//内部函数,设置一行选种样式

function setRowCss(row, selected)

{

if (selected == null)

selected = row.selected;

if (selected == null)

selected = false;

if (!selected)

{

if (row.rowIndex % 2 == 0)

{

for (var i = 0; i < row.children.length; ++i)

row.children[i].style.cssText = columns[i].style1;

}

else

{

for (var i = 0; i < row.children.length; ++i)

row.children[i].style.cssText = columns[i].style2;

}

}

else

{

if (row.rowIndex % 2 == 0)

{

for (var i = 0; i < row.children.length; ++i)

row.children[i].style.cssText = columns[i].style11;

}

else

{

for (var i = 0; i < row.children.length; ++i)

row.children[i].style.cssText = columns[i].style22;

}

}

for (var i = 0; i < row.children.length; ++i)

{

if (i == 0)

row.children[i].style.width = parseInt(columns[i].colHeader.style.width) + 2;

else

row.children[i].style.width = parseInt(columns[i].colHeader.style.width) + 4;

}

row.selected = selected

}

//方法实现,设置某一行的选种状态

function selectRow(rowIndex, selected)

{

var row = rows[rowIndex];

if (row == null)

return row;

if (selected)

{

setRowCss(row, true);

if (selectedRows.length > 0 && selectedRows[selectedRows.length - 1].rowIndex == rowIndex);

else

{

selectedRows[selectedRows.length] = row;

selChange.fire();

}

}

else

{

setRowCss(row, false);

}

return row;

}

//方法实现

function clearSelect()

{

clickRow(-1);

}

//内部函数

function setColWidth()

{

if (rows.length <= 0)

return;

var tableWidth = 0;

for (var i = 0; i < columns.length; ++i)

{

if (i == 0)

columns[i].colHeader.style.width = rows[0].children[i].clientWidth - 2;

else

columns[i].colHeader.style.width = rows[0].children[i].clientWidth - 4;

tableWidth += parseInt(columns[i].colHeader.style.width) + 4;

}

dataTable.width = tableWidth - 2;

}

//方法实现

function addRow(rowData)

{

var row = dataTable.insertRow();

row.onmousedown = new Function("clickRow(" + row.rowIndex + ")");

row.ondblclick = new Function("var eventObject = createEventObject();eventObject.rowIndex = "

+ row.rowIndex + ";wantEdit.fire(eventObject);");

for (var i = 0; i < rowData.length; ++i)

{

var td = row.insertCell();

td.innerHTML = rowData[i];

}

setRowCss(row, false);

//setColWidth();

return row;

}

Array.prototype.remove = function(dx)

{

if(isNaN(dx)||dx>this.length){return false;}

this.splice(dx, 1);

}

//方法实现

function delRow(rowIndex)

{

dataTable.deleteRow(rowIndex);

//重新格式化

for (var i = 0; i < rows.length; ++i)

{

rows[i].onmousedown = new Function("clickRow(" + i + ")");

rows[i].ondblclick = new Function("wantEdit.fire(" + i + ")");

setRowCss(rows[i], false);

}

//如果删除了已经选中的

var k = -1;

for (var i = 0; i < selectedRows.length; ++i)

{

if (selectedRows[i].rowIndex == -1)

k = i;

else

setRowCss(selectedRows[i], true);

}

if (k >= 0)

selectedRows.remove(k);

}

</script>

测试文件(test_htc_listView.aspx)如下:

<%@ Page language="c#" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>test_htc_listView</title>

<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">

<meta name="CODE_LANGUAGE" Content="C#">

<meta name="vs_defaultClientScript" content="JavaScript">

<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

<script>

function init()

{

lv1.addColumn

(

200,

"Added",

"color:green;BORDER-BOTTOM: green 1px dashed;BACKGROUND-COLOR: #EED881",

"color:green;BORDER-BOTTOM: green 1px dashed;BACKGROUND-COLOR: #EFE6C1",

"color:white;BORDER-BOTTOM: green 1px dashed;BACKGROUND-COLOR: black",

"color:white;BORDER-BOTTOM: green 1px dashed;BACKGROUND-COLOR: black"

);

}

function addData()

{

var data = new Array();

data[1] = "kasdkf<br>kaskd";

data[2] = "Liuk<br>as";

data[3] = "com<br>asss";

data[4] = "FF";

data[5] = "gaGG";

for (var i = 0; i < 5; ++i)

{

data[0] = 'A ' + i + '';

lv1.addRow(data);

}

data[1] = "HH";

data[2] = "FF";

data[3] = '<span style="overflow:hidden">KKKKKSSSS呵呵</span>';

data[4] = "rr";

data[5] = "kk";

for (var i = 0; i < 5; ++i)

{

data[0] = '<span style="width:100%;height:100%;text-align:center">G ' + i + '</span>';

var row = lv1.addRow(data);

}

lv1.clearSelect();

lv1.selectRow(0, true);

}

function delCur()

{

var oldSel = lv1.selectedRows[0].rowIndex;

while (lv1.selectedRows.length > 0)

lv1.delRow(lv1.selectedRows[0].rowIndex);

lv1.selectRow(oldSel, true);

}

function wantEdit()

{

alert(event.rowIndex + "行想被编辑!");

}

function headClick()

{

alert("用户点击了第“" + event.colIndex + "”列,你可以排序,也可以什么都不干!");

}

</script>

</HEAD>

<body MS_POSITIONING="GridLayout" bgcolor="menu" style="FONT-SIZE: 9pt; OVERFLOW: hidden"

onload="init();">

<span id="lv1" style="BORDER-RIGHT: thin inset; BORDER-TOP: thin inset; LEFT: 0px; BEHAVIOR: url(/spanClient/htc_listView.htc); BORDER-LEFT: thin inset; WIDTH: 100%; BORDER-BOTTOM: thin inset; TOP: 0px; HEIGHT: 80%; BACKGROUND-COLOR: white"

singleSelect='false' onwantedit="wantEdit()" onheadclick="headClick()" freezeCols='false'>

<xml>

<columns>

<column width="50" text="col1" style1="background-color: #DADFF1;" style2="background-color: #B9C1DD;"

style11="background-color: #DADFF1;" style22="background-color: #B9C1DD;" />

<column width="100" text="col2" style1="background-color: green;" style2="background-color: green;" />

<column width="100" text="col3" />

<column width="100" text="col4" />

<column width="100" text="col5" />

</columns>

</xml>

</span>

<br>

<br>

<input type="button" value="增加" style="WIDTH:60px;HEIGHT:23px" onclick="addData();">

&nbsp;&nbsp;&nbsp;&nbsp; <input type="button" value="删除" style="WIDTH:60px;HEIGHT:23px" onclick="delCur();">

</body>

</HTML>

另外,还有两张图片:

headerBg.gif:

以及headerSplit.gif:

尽管这样反白,也不知道你能不能看清楚。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有