赞
踩
一直以来winform的listview都只是作为数据输出显示来用, 想要实现数据的双向操作比较难
之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能, 而且其中有很大一部分是ocx组件,
那么就需要在客户电脑上regsvr32 注册它, 这样就需要管理员权限, 这样操作并不是很好,
于是考虑着手动改造listview使其满足我的需求.
还好, aardio范例里有个数据视图win.ui.grid的库可供参考, 我就是根据这个库内的实现方法来升级改造的.
下面我在原listview grid基础上增加了, 双击指定列 可直接编辑文本 / 弹出下拉框选择文本 功能.
listviewEX.aardio 库代码如下:
- //listview 扩展
- import win.ui.ctrl.edit;
- import win.ui.ctrl.combobox;
- namespace win.ui;
- class listviewEx{
- ctor( listview ){
- this = listview;
- this.fullRow = 1;
- this.gridLines = 1;
- this.columnsEditbox = {};//记录编辑框列号
- this.columnsCombobox = {};//记录下拉框列号和列表值
- //添加下拉框模板
- this.addCtrl(
- combobox = {
- cls="combobox";font = LOGFONT( h = -19 );left = 0;top = 0;
- right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1;mode="dropdownlist";
- wndproc = function( hwnd, message, wParam, lParam ){
- var update;
- var event = owner.event;
-
- if( message == 308 ) {
- update = true;
- }
- if( update ){
- owner.show(false);
- var t = this.getItemText(event.iItem,event.iSubItem );
- if( t!= owner.text ){
- if( this.onEditChanged ) {
- if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem))
- return;
- }
-
- this.setItemText( owner.text, event.iItem, event.iSubItem );
- }
-
- if(this.onEditEnd){
- this.onEditEnd(event.iItem, event.iSubItem);
- }
- }
- }
- }
- );
- //添加编辑框模板
- this.addCtrl(
- editBox = {
- cls="edit";font = LOGFONT( h = -19 );left = 0;top = 0;
- right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1;
- wndproc = function( hwnd, message, wParam, lParam ){
- var update;
- var event = owner.event;
-
- if( ( message = 0x8/*_WM_KILLFOCUS*/) || (message == 0x101/*_WM_KEYUP*/ && wParam == 0xD/*_VK_RETURN*/ ) ) {
- update = true;
- }
- elseif(message == 0x201/*_WM_LBUTTONDOWN*/ ){
- var x,y = ..win.getMessagePos(lParam)
- var rc = this.editBox.getClientRect();
-
- if( ! ::PtInRect(rc,x,y) ) update = true;
- this.editBox.capture = !update;
- }
- elseif(message == 0x101/*_WM_KEYUP*/){
- if( wParam == 0xD/*_VK_RETURN*/ ) update = true;
- elseif( wParam == 0x1B/*_VK_ESC*/){
- owner.text = this.getItemText(event.iItem,event.iSubItem );
- update = true;
- }
- }
- if( update ){
- owner.show(false);
- var t = this.getItemText(event.iItem,event.iSubItem );
- if( t!= owner.text ){
- if( this.onEditChanged ) {
- if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem))
- return;
- }
-
- this.setItemText( owner.text, event.iItem, event.iSubItem );
- }
-
- if(this.onEditEnd){
- this.onEditEnd(event.iItem, event.iSubItem);
- }
- }
- }
- }
- )
- };
- //绘制下拉框
- beginCombobox = function(iItem,iSubItem){
- var combobox = this.combobox;
- if( ..win.isVisible(combobox.hwnd) ) return;
-
- var event = this.combobox.event;
- if(iItem===null && iSubItem===null) {
- iItem = event.iItem;
- iSubItem = event.iSubItem;
- }
- else {
- event = {
- iItem = iItem;
- iSubItem = iSubItem;
- };
- combobox.event = event;
- }
-
- combobox.items = this.columnsCombobox[iSubItem];
- combobox.selText=this.getItemText(iItem,iSubItem);
- var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ );
-
- rc.inflate(2,2);
- combobox.setRect(rc);
- combobox.showDropDown();
- return true;
- };
- //绘制编辑框
- beginEdit = function(iItem,iSubItem){
- var edit = this.editBox;
- if( ..win.isVisible(edit.hwnd) ) return;
-
- var event = this.editBox.event;
- if(iItem===null && iSubItem===null) {
- iItem = event.iItem;
- iSubItem = event.iSubItem;
- }
- else {
- event = {
- iItem = iItem;
- iSubItem = iSubItem;
- };
- edit.event = event;
- }
-
- edit.text=this.getItemText(iItem,iSubItem);
- var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ );
-
- rc.inflate(2,2);
- edit.setRect(rc);
- edit.show();
- edit.setFocus();
- edit.capture = true;
- return true;
- };
- //设置下拉框模式 列号/下拉值
- setcolumnsCombobox = function(iSubItem,tab,...){
- var c = type(tab) === "table" ? tab : {tab,...}
- this.columnsCombobox[iSubItem] = c;
- };
- //设置编辑框模式 列号
- setcolumnsEditbox = function(...){
- var c = type(...) === "table" ? ... : {...}
- for(i,idx in c) this.columnsEditbox[idx] = 1;
- };
- prenotify = {
- [0xFFFFFFFD/*_NM_DBLCLK*/] = function(id,code,ptr){
- var event = this.getNotifyMessage(code,ptr);
- if( ! event.iItem && event.iSubItem ) return ;
- //启用 编辑框
- if( this.columnsEditbox[event.iSubItem] ){
- this.editBox.event = event;
- this.beginEdit();
- };
- //启用 下拉框
- if( this.columnsCombobox[event.iSubItem] ){
- this.combobox.event = event;
- this.beginCombobox();
- };
- };
- }
- }
-
-
- /**intellisense()
- win.ui.listviewEx(__) = 参数必须指定一个listview控件对象\n返回一个可编辑单元格的列表视图对象,\n\n鼠标左键单击单元格、或者按空格键开始编辑,\n回车完成编辑,ESC键撤消编辑,回车+上下方向键快速移动到其他项,\n用户完成编辑后会触发onEditChanged事件.\n!listview.
- win.ui.listviewEx() = !win_ui_listviewEx.
- !win_ui_listviewEx.edit = 实现编辑功能的edit控件\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n!edit.
- !win_ui_listviewEx.combobox = 实现编辑功能的edit控件\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n!combobox.
- !win_ui_listviewEx.onEditChanged(text,iItem,iSubItem) = @.onEditChanged = function(text,iItem,iSubItem){
- __/*控件完成编辑,并且文本已变更,\ntext为改变后的文本,iItem为行号,iSubItem为列号\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n返回false可中止更新显示文本*/
- }
- !win_ui_listviewEx.onEditEnd(iItem,iSubItem) = @.onEditEnd = function(iItem,iSubItem){
- __/*控件完成编辑*/
- }
- !win_ui_listviewEx.setTable(__) = 用listview控件显示数据表\n此函数会自动清空控件之前的所有项,\n如果没有创建任何列,则自动创建列\n\n数据表应当包含行组成的数组,\n每行的数据列必须是由列名和列值组成的键值对\n数据表应使用fields包含需要显示的列名称数组\n可以通过fields控制要显的列、以及要显示的顺序\n\n使用sqlite,access,sqlServer等数据库对象提供的getTable函数可获取符合此规格的数据表
- !win_ui_listviewEx.setColumns(__) = 用一个字符串数组指定要显示的列\n如果参数为空则清空所有列
- !win_ui_listviewEx.setcolumnsCombobox(__) = 可以使用一个或多个参数指定要禁止编辑的列序号,\n也可以用一个数组参数指定多个列序号
- !win_ui_listviewEx.setcolumnsEditbox(__) = 可以使用一个或多个参数指定要编辑的列序号,\n也可以用一个数组参数指定多个列序号
- !win_ui_listviewEx.clear() = 清空所有行
- !win_ui_listviewEx.clear(true) = 清空所有行,并且清空所有列
- end intellisense**/
使用也很简单, 只需要指定哪一列是文本框模式, 哪一列是下拉框模式.
- import win.ui;
- /*DSG{{*/
- mainForm = win.form(text="testListviewEx";right=740;bottom=315;bgcolor=16777215)
- mainForm.add(
- listview={cls="listview";left=13;top=8;right=729;bottom=309;border=1;db=1;dl=1;dr=1;dt=1;font=LOGFONT(h=-13);fullRow=1;gridLines=1;msel=false;vscroll=1;z=1}
- )
- /*}}*/
-
- import console
- console.open()
-
- import win.ui.listviewEx;
- var grid = win.ui.listviewEx(mainForm.listview);
- grid.setcolumnsEditbox(2);
- grid.setcolumnsCombobox(3,"10","1000","2000","5000");
- grid.setcolumnsCombobox(4,{"Z+","Z-","ZNP+","ZNP-"});
- grid.setcolumnsCombobox(5,{"急停","减速停"});
- grid.onEditChanged = function(text,iItem,iSubItem){
- console.log("onEditChanged",text,iItem,iSubItem)
- }
-
-
- import win.imageList;
- var iml = win.imageList(1,30);
- mainForm.listview.setImageList( iml,1/*_LVSIL_NORMAL*/ );
- mainForm.listview.setColumns(
- {"轴号","加减速时间","单脉冲运动量","找零方式","停止方式"},
- {60,120,120,100,100},
- {2,2,2,2,2},
- );
- var axisData = {};
- for(i=1;20;1){
- axisData[i]={};
- axisData[i][1] = "轴"++i;
- axisData[i][2] = "0.1";
- axisData[i][3] = "1";
- axisData[i][4] = "Z+";
- axisData[i][5] = "急停";
- }
- mainForm.listview.items = axisData;
-
-
- mainForm.show();
- return win.loopMessage();
主要看上面部分, 上面声明完所有的列功能, 下面还是用listview自己的功能实现代码.
完整示例工程可以去我的博客下载:
另外, 如果有更新会在我的博客第一时间更新, 有代码方面的问题也可以去那里跟帖提问.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。